7

GCC 编译器

$ gcc --version
gcc (GCC) 4.8.2
...

不会生成inc汇编指令,它实际上可能有用,就像在这个 C 程序中一样:

int main(int argc, char **argv)
{
    int sum = 0;
    int i;
    for(i = 0; i < 1000000000L; i++)                     <---- that "i++"
        sum += i;
    return sum;
}

相反,它会生成一条add指令:

0000000000000000 <main>:
   0:   31 d2                   xor    %edx,%edx
   2:   31 c0                   xor    %eax,%eax
   4:   0f 1f 40 00             nopl   0x0(%rax)
   8:   01 d0                   add    %edx,%eax
   a:   83 c2 01                add    $0x1,%edx         <---- HERE
   d:   81 fa 00 ca 9a 3b       cmp    $0x3b9aca00,%edx
  13:   75 f3                   jne    8 <main+0x8>
  15:   f3 c3                   repz retq 

为什么这样做?

编辑:我曾经gcc -O2编译过这个。gcc -Os确实会生成inc指令。不是使用inc更多的速度优化而不是空间优化吗?

4

2 回答 2

12

试试看-march=<your machine>。结果可能不同。

但是,请注意,这add $1, %reg不一定是一个糟糕的选择。尽管incdec具有较小的编码,这很有吸引力,但它们受到以下事实的困扰:它们仅部分更新标志,从而导致错误的依赖问题。英特尔优化手册包含此评论(我的重点):

INC 和 DEC 指令只修改标志寄存器中的一部分位。这对标志寄存器的所有先前写入产生了依赖性。当这些指令位于关键路径上时,这尤其成问题,因为它们用于更改许多其他指令所依赖的负载的地址。汇编/编译器编码规则 33.(M 影响,H 通用性)INC 和 DEC 指令应替换为 ADD 或 SUB 指令,因为 ADD 和 SUB 会覆盖所有标志,而 INC 和 DEC 不会,因此会创建对早期指令的错误依赖设置标志。

于 2013-11-10T13:44:33.693 回答
4

可能确实取决于您正在使用(或不使用)的确切优化设置。可以告诉 GCC 优化时间或空间(尽管优化空间有时可能是优化执行时间的有效方法!)

仅仅因为指令可用于专业任务,并不意味着它一定是最有效的使用指令。

一些旧的 x86 指令实际上是在微码中实现的,而不是在硬件中,因为它们很少使用并且不值得在硬件中实现。但这会使它们变慢。我不知道 inc 是否是这样的指令。

此外,如果您不告诉 GCC 您将在哪个 x86 处理器型号上运行代码,那么它将不得不猜测一些通用的东西。

于 2013-11-10T13:22:38.013 回答