由gcc编译的程序比g ++编译的程序运行得更快

时间:2012-10-27 21:04:25

标签: c performance gcc g++

  

可能重复:
  Performance difference between gcc and g++ for C program

当我意外地注意到用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

2 个答案:

答案 0 :(得分: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编译器产生了更好的循环测试。不要问我为什么,我不知道。

答案 1 :(得分: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