7

可能重复:
C 程序的 gcc 和 g++ 之间的性能差异

当我偶然注意到使用 gcc 编译的程序比使用 g++ 编译的程序运行得更快时,我正在检查使用循环控制变量的寄存器存储说明符来提高性能。有人可以向我解释吗?

这是代码:

#include <stdio.h>

const unsigned long scope = 1000000000;

int main()
{
    register unsigned long i;
    for (i=0; i < scope; i++);
    return 0;
}

;

gcc register.c
time ./a.out   
real    0m0.466s
user    0m0.468s
sys     0m0.000s

g++ register.c
time ./a.out 
real    0m0.923s
user    0m0.920s
sys     0m0.000s
4

2 回答 2

4

我可以重现行为(gcc-4.6.2),生成的程序集的相关部分是

C:

.L3:
    addq    $1, %rbx
.L2:
    movq    scope(%rip), %rax
    cmpq    %rax, %rbx
    jb      .L3

C++:

.L3:
    addq    $1, %rbx
.L2:
    cmpq     $999999999, %rbx
    setbe    %al
    testb    %al, %al
    jne      .L3

因此 C 编译器产生了更好的循环测试。不要问我为什么,我不知道。

于 2012-10-27T21:19:40.107 回答
1

虽然我无法在 i5 M520 ( gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3) 上获得相同的结果,但我确实看到了反汇编输出的差异。

$ sdiff f.S  f_cpp.S 
...
00000000004004b4 <main>:                                        00000000004004b4 <main>:
  4004b4:       55                      push   %rbp               4004b4:       55                      push   %rbp
  4004b5:       48 89 e5                mov    %rsp,%rbp          4004b5:       48 89 e5                mov    %rsp,%rbp
  4004b8:       53                      push   %rbx               4004b8:       53                      push   %rbx
  4004b9:       bb 00 00 00 00          mov    $0x0,%ebx          4004b9:       bb 00 00 00 00          mov    $0x0,%ebx
  4004be:       eb 04                   jmp    4004c4 <main+0     4004be:       eb 04                   jmp    4004c4 <main+0
  4004c0:       48 83 c3 01             add    $0x1,%rbx          4004c0:       48 83 c3 01             add    $0x1,%rbx
  4004c4:       48 8b 05 05 01 00 00    mov    0x105(%rip),%r |   4004c4:       48 81 fb ff c9 9a 3b    cmp    $0x3b9ac9ff,%r
  4004cb:       48 39 c3                cmp    %rax,%rbx      |   4004cb:       0f 96 c0                setbe  %al
  4004ce:       72 f0                   jb     4004c0 <main+0 |   4004ce:       84 c0                   test   %al,%al
  4004d0:       b8 00 00 00 00          mov    $0x0,%eax      |   4004d0:       75 ee                   jne    4004c0 <main+0
  4004d5:       5b                      pop    %rbx           |   4004d2:       b8 00 00 00 00          mov    $0x0,%eax
  4004d6:       5d                      pop    %rbp           |   4004d7:       5b                      pop    %rbx
  4004d7:       c3                      retq                  |   4004d8:       5d                      pop    %rbp
  4004d8:       90                      nop                   |   4004d9:       c3                      retq   
  4004d9:       90                      nop                   <
  4004da:       90                      nop                       4004da:       90                      nop
  4004db:       90                      nop                       4004db:       90                      nop

以下是 gcc/C 在分析时的表现:

 Percent |  Source code & Disassembly of f_c
------------------------------------------------
         :
         :
         :
         :  Disassembly of section .text:
         :
         :  00000000004004b4 <main>:
    0.00 :    4004b4:       push   %rbp
    0.00 :    4004b5:       mov    %rsp,%rbp
    0.00 :    4004b8:       push   %rbx
    0.00 :    4004b9:       mov    $0x0,%ebx
    0.00 :    4004be:       jmp    4004c4 <main+0x10>
   48.97 :    4004c0:       add    $0x1,%rbx
    0.00 :    4004c4:       mov    0x105(%rip),%rax        # 4005d0 <scope>
   51.03 :    4004cb:       cmp    %rax,%rbx
    0.00 :    4004ce:       jb     4004c0 <main+0xc>
    0.00 :    4004d0:       mov    $0x0,%eax
    0.00 :    4004d5:       pop    %rbx
    0.00 :    4004d6:       pop    %rbp

以下是 g++ 在分析时的表现:

 Percent |  Source code & Disassembly of g_cpp
------------------------------------------------
         :
         :
         :
         :  Disassembly of section .text:
         :
         :  00000000004004b4 <main>:
    0.00 :    4004b4:       push   %rbp
    0.00 :    4004b5:       mov    %rsp,%rbp
    0.00 :    4004b8:       push   %rbx
    0.00 :    4004b9:       mov    $0x0,%ebx
    0.00 :    4004be:       jmp    4004c4 <main+0x10>
   49.49 :    4004c0:       add    $0x1,%rbx
    0.00 :    4004c4:       cmp    $0x3b9ac9ff,%rbx
   11.24 :    4004cb:       setbe  %al
   39.27 :    4004ce:       test   %al,%al
    0.00 :    4004d0:       jne    4004c0 <main+0xc>
    0.00 :    4004d2:       mov    $0x0,%eax
    0.00 :    4004d7:       pop    %rbx
    0.00 :    4004d8:       pop    %rbp
于 2012-10-27T21:12:12.480 回答