ADD 1真的比INC快吗? 86

时间:2012-11-14 16:53:41

标签: performance optimization assembly x86

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

3 个答案:

答案 0 :(得分:28)

在一些微架构上,对于某些指令流,INC将导致“部分标志更新停顿”(因为它会在保留其他标志的同时更新一些标志)。 ADD设置所有标志的值,因此不会冒这样的失误。

ADD并不总是比INC更快,但它几乎总是至少一样快(在某些较旧的微架构上存在一些极端情况,但它们非常罕见),并且有时会明显加快。

有关详细信息,请参阅Intel's Optimization Reference ManualAgner Fog's micro-architecture notes

答案 1 :(得分:4)

虽然这不是一个明确的答案。写下这个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

请注意生成的汇编代码。相关的铿锵声:

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一样快,并且由于寄存器编码较短而节省的一个字节使它更受欢迎。编译器作者只是人,所以他们可能是错的,但不太可能。 :)

更多实验告诉我,如果您不使用add ebx, 1选项,那么gcc将使用ADD代替。 Clang otoh,总是喜欢最好的。我的结论是,当您在2012年提出问题INC时,有时候会更好,但现在在2016年,您应该始终使用{{1}}。

答案 2 :(得分:-1)

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

然后是时代,当英特尔以CISC类型指令为代价特别优化了大多数RISC类型的指令。 (例如,添加ax,[mem];添加[mem],ax)。今天或者至少明天,这些都很便宜......复杂的分支序列将在30个单元的流水线中解析,自动重新命名。

所以,我们现在更有可能处于inc eax CISC 的时代,又名不好,而add eax,1 RISC ,这是好。但这些事情可能会在一夜之间发生变化。