我已阅读各种优化指南,声称 ADD 1 比在 x86 中使用 INC 更快。这是真的吗?
问问题
7188 次
2 回答
31
在某些具有某些指令流的微架构上,INC
将导致“部分标志更新停顿”(因为它更新了一些标志,同时保留了其他标志)。 ADD
设置所有标志的值,因此不会冒这种停顿的风险。
ADD
并不总是比 快INC
,但它几乎总是至少一样快(在某些较旧的微架构上存在一些极端情况,但它们非常罕见),有时甚至快得多。
有关更多详细信息,请参阅Intel 的优化参考手册或Agner Fog 的微架构说明。
于 2012-11-14T16:58:07.973 回答
6
虽然这不是一个确定的答案。编写这个 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
这证明了 clang 和 gcc 的作者都认为在现代架构上INC
是更好的选择。ADD reg, 1
这对你的问题意味着什么?好吧,我相信他们对您已阅读的指南的判断,并得出结论,这与由于较短的寄存器编码而节省的一个字节INC
一样快,因此更可取。ADD
编译器作者只是人,所以他们可能会出错,但这不太可能。:)
更多的实验告诉我,如果您不使用该-march=native
选项,那么 gcc 将add ebx, 1
改为使用。Clang otoh,总是最喜欢 inc。我的结论是,当你在 2012 年问这个问题时,ADD
有时更可取,但现在在 2016 年你应该总是选择INC
.
于 2016-05-08T02:17:36.820 回答