【发布时间】:2014-11-19 08:33:12
【问题描述】:
以如下代码为例:
uint32_t fg;
uint32_t bg;
uint32_t mask;
uint32_t dest;
...
dest = (fg & mask) | (bg & (~mask));
现在这个片段的所有操作数都是 32 位无符号整数类型的。使用 32 位 int 大小的 C 编译器,不会发生整数提升,因此整个操作都是在 32 位中执行的。
我的问题是,例如on Wikipedia 表明,通常即使是 64 位机器也会拥有使用 32 位 int 大小的编译器。符合 C 标准,它们不会将操作数提升为 64 位整数,因此可能会编译成性能较差且代码大小可能更大的东西(只是假设 16 位操作在周期和指令大小方面的成本更高) 32 位 x86)。
主要问题是:我需要担心吗? (我相信我可能不会,因为启用优化后,一个理智的编译器可能能够省略严格遵循 C 标准会出现的多余的垃圾。请查看示例代码,并一般认为我的信念可能更少地面)
如果是这样(我实际上必须担心),您能否推荐一些涵盖该领域的方法(书籍、网站等)? (好吧,我知道这对 SO 来说有点过分,但是如果我只得到三个字 Yes, you do! 作为接受的答案,我认为这不太有用)
【问题讨论】:
-
"只是假设在 32 位 x86 上 16 位操作在周期和指令大小方面的成本更高" 真的是这样吗?
-
@glglgl:是的,由于指令上的操作数大小前缀导致了额外的大小,至少在较旧的 Pentium 上,需要额外的周期来处理它(我没有在这方面检查较新的处理器)。
-
@Jubatian 你是在说 x86-64 架构,还是任何 64 位架构?
-
@anatolyg:现在和这里可能主要是 x86-64,但为了跨平台而保持通用。如果即使在一个相当常见的架构(例如 ARM 64 位)上也存在一些问题,也值得一提。
-
C 中的
int应该是架构的“自然”操作数大小。在 32 位操作比 64 位操作花费更长的架构上,sizeof(int)*CHAR_BIT应该是64。也就是说,在 x86-64 上,默认操作数大小仍然是 32 位,而不是 64 位。因此,32 位操作不需要操作数大小前缀,并且不比 64 位操作慢。
标签: c performance optimization