微优化:使用intptr_t作为flag / bool类型

时间:2010-08-12 17:19:37

标签: c x86-64 c99 micro-optimization systems-programming

根据我的理解,intptr_t的定义因架构而异 - 它保证能够表示可以访问进程的所有统一地址空间的指针。

Nginx(流行的开源Web服务器)定义了一个用作标志(boolean)的类型,这个类型定义为intptr_t。现在使用x86-64架构作为示例 - 可以访问涵盖所有大小操作数的大量指令 - 为什么要将标志定义为intptr_t?当然,使用32位bool类型的传统也符合要求吗?

我已经超过32位Vs.当我是一名新开发人员时,8位bool自己的论点,结论是32位bool在常见情况下表现更好,因为处理器设计错综复杂。那为什么需要转向64位bool?

2 个答案:

答案 0 :(得分:2)

唯一真正知道为什么nginx使用intptr_t作为布尔类型的人是nginx开发人员。

正如你所说,对于普通情况,32位bool通常比8位bool表现更好。我自己没有做过基准测试,但对于我而言,对于x86-64的特定情况,64位bool击败32位bool听起来并不合理。例如,在nginx源代码中,我注意到大多数ngnx_flag_t出现在具有其他(u)intptr_t typedef'类型的结构中。由于对齐填充,32位bool可能无法节省空间。

我发现intptr_t的选择有点奇怪,因为它是一个可选的C99类型,目的是转换为/ void *。但据我所知,它从未被用过。也许这种类型给出了'原生'字大小类型的最佳近似值?

答案 1 :(得分:1)

对于x86-64来说,64位bool听起来很糟糕。我猜想写这篇文章的人当时正在考虑使用32位指针的32位机器。

Modern x86非常好地支持未对齐的加载/存储,以及解压缩一个字节以便动态填充寄存器。如果x86是主要目标,则应首选8位布尔值,尤其是在保存字节数导致较少缓存使用量的情况下。在极少数情况下,缓存根本不是问题,32bit是自然大小,并且可以在某些情况下保存指令,其中添加布尔值或直接与let url = NSURL(string: "https://webapi.tab.com.au/v1/tab-info-service/racing/dates/2015-12-28/meetings?jurisdiction=NSW")! let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) -> Void in if let urlContent = data { do { let jsonResult = try NSJSONSerialization.JSONObjectWithData(urlContent, options: NSJSONReadingOptions.MutableContainers) print(jsonResult) // Code for unwrapping 'jsonResult' // End of unwrapping 'If you worked it out, thank you!!!!!!!!! } catch { print("Error") } } } task.resume() 相乘,方法是允许布尔值为用作内存操作数,而不是加载int

对于boolean上测试和分支的常见情况,Intel和AMD CPU在8位和32位操作数之间的性能差异确实为零,无论是在内存还是寄存器中。