Tyl*_*den 17 optimization performance x86 assembly
我已经阅读了各种优化指南,声称ADD 1比在x86中使用INC更快.这是真的吗?
Ste*_*non 29
在某些微架构上,使用一些指令流INC会产生"部分标志更新停顿"(因为它会在保留其他标志的同时更新一些标志). ADD设置所有标志的值,因此不会冒这样的停顿.
ADD并不总是比INC它快,但它几乎总是至少一样快(在某些较旧的微架构上有一些极端情况,但它们非常罕见),有时速度要快得多.
有关更多详细信息,请参阅英特尔优化参考手册或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;
}
Run Code Online (Sandbox Code Playgroud)
然后运行:
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
Run Code Online (Sandbox Code Playgroud)
注意生成的汇编代码。相关的clang输出:
mov esi, ebx
call printf
inc ebx
cmp ebx, 1000
jne .LBB0_1
Run Code Online (Sandbox Code Playgroud)
相关的 gcc 输出:
mov edi, 1
inc ebx
call __printf_chk
cmp ebx, 1000
jne .L2
Run Code Online (Sandbox Code Playgroud)
这证明了 clang 和 gcc 的作者都认为INC是ADD reg, 1现代架构上更好的选择。
这对你的问题意味着什么?好吧,我相信他们对您阅读的指南的判断,并得出结论,这与由于较短的寄存器编码而节省的一个字节INC一样快ADD,因此更可取。编译器作者只是普通人,所以他们可能会出错,但这不太可能。:)
更多的实验告诉我,如果您不使用该-march=native选项,那么 gcc 将add ebx, 1改为使用。Clang otoh,总是最喜欢公司。我的结论是,当您在 2012ADD年问这个问题时有时更可取,但现在在 2016 年您应该始终使用INC.