【问题标题】:Micro-optimizations: using intptr_t for flag/bool types微优化:将 intptr_t 用于标志/布尔类型
【发布时间】:2010-08-12 17:19:37
【问题描述】:

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

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

我已经了解了 32 位 Vs。当我还是一名新开发人员时,我自己争论 8 位布尔值,结论是由于处理器设计的复杂性,32 位布尔值在常见情况下表现更好。那么为什么需要迁移到 64 位布尔值呢?

【问题讨论】:

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


    【解决方案1】:

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

    正如您所说,在常见情况下,32 位布尔值的性能通常优于 8 位布尔值。我自己没有做过基准测试,但在 x86-64 上的某些情况下,64 位布尔值优于 32 位布尔值对我来说并非不合理。例如,在 nginx 源代码中,我注意到大多数 ngnx_flag_t 出现在具有其他 (u)intptr_t typedef 类型的结构中。由于对齐填充,32 位 bool 可能不会在此处节省空间。

    我确实发现 intptr_t 的选择有点奇怪,因为它是一个可选的 C99 类型,目的是与 void * 进行转换。但据我所知,它从来没有被这样使用过。也许这种类型给出了“本机”字大小类型的最佳近似值?

    【讨论】:

      【解决方案2】:

      64bit bool 对于 x86-64 来说听起来是个糟糕的主意。我猜写它的人当时正在考虑使用 32 位指针的 32 位机器。

      现代 x86 对未对齐的加载/存储以及解包字节以动态填充寄存器有很好的支持。如果 x86 是主要目标,则应首选 8 位布尔值,尤其是在它节省字节从而减少缓存使用的情况下。在缓存根本不是问题的极少数情况下,32 位是自然大小,并且在某些情况下可能会通过允许布尔值被用作布尔值来节省指令一个内存操作数,而不是使用 movzx 加载。

      对于布尔值上的 test&branch 的常见情况,Intel 和 AMD CPU 在 8 位和 32 位操作数之间的性能差异几乎为零,无论是在内存中还是在寄存器中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-03-22
        • 2013-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-30
        相关资源
        最近更新 更多