19

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

4

2 回答 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 回答