ADD 1真的比INC快吗? x86

我已经阅读了各种优化指南,声称ADD 1比在x86中使用INC更快。 这是真的吗?

在一些微架构上,对于一些指令stream, INC会产生“部分标志更新失速”(因为它更新了一些标志,同时保留了其他标志)。 ADD设置所有标志的值,所以不会冒这样的失速。

ADD并不总是比INC快,但几乎总是至less一样快(在某些较旧的微架构上有一些angular落的情况,但它们非常罕见),有时甚至更快。

有关更多详细信息,请参阅英特尔优化参考手册或Agner Fog的微架构笔记 。

虽然这不是一个确定的答案。 写这个C文件:

 === inc.c === #include <stdio.h> int main(int argc, char *argv[]) { for (int n = 0; n < 1000; n++) { printf("%d\n", n); } return 0; } 

然后运行:

 clang -march=native -masm=intel -O3 -S -o inc.clang.s inc.c gcc -march=native -masm=intel -O3 -S -o inc.gcc.s inc.c 

注意生成的汇编代码。 相关的clang输出:

 mov esi, ebx call printf inc ebx cmp ebx, 1000 jne .LBB0_1 

相关的gcc输出:

 mov edi, 1 inc ebx call __printf_chk cmp ebx, 1000 jne .L2 

这certificate了clang和gcc的作者都认为INC是现代架构中ADD reg, 1的更好select。

这对你的问题意味着什么? 那么,我会相信他们对你读过的指南的判断,并得出结论: INCADD一样快,并且由于较短的寄存器编码而节省了一个字节,所以它更可取。 编译器作者只是人,所以他们可能是错的,但不太可能。 🙂

一些更多的实验表明,如果你不使用-march=native选项,那么gcc将使用add ebx, 1而不是add ebx, 1 。 铿锵,总是喜欢最好的公司。 我的结论是,当你在2012年问这个问题时, ADD有时候是可取的,但现在在2016年,你应该总是和INC一起去。

在80年代或90年代,简单的指令执行时间主要取决于指令中的组件数量:add ax,1包含一个更多的可解码单位(立即数),相比于inc ax或者增加ax,bx。 因此80286花了一个时钟周期来解码指令。

那么就有这个时代,当时英特尔特别是以CISC型指令为代价来优化大多数RISC型指令。 (例如添加ax,[mem];添加[mem],ax)。 今天或至less明天,这些都是便宜的…复杂的分支序列将被解决在30单位pipe道,自动寄存器重命名。

所以,现在我们更有可能在这个时代,在这个时代, inc eaxCISC ,也叫坏add eax,1RISC ,这是好的。 但是这些事情可以在一夜之间改变。