使用gcc编译的程序比使用g++编译的程序运行更快

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
看这个拆卸。 - Carl Norum
1
优化级别可能不同。 - Anirudh Ramanathan
在我的硬件上无法重现您的结果。您使用的gcc版本是哪个? - Brian Cain
C程序中gcc和g++之间的性能差异 - P.P
@KingsIndian 当然... :) - Memos Electron
显示剩余3条评论
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编译器生成了更好的循环测试。不要问我为什么,我也不知道。


1
因为在C++中,const是一个常量表达式,就像内联写入值一样,代码会被编译成这样。在C语言中,const是一个不可变的变量,并且由于它具有外部链接性,gcc生成了它并生成了对它的实际访问。这可能可以避免,但检测可以避免的条件并不完全简单。 - R.. GitHub STOP HELPING ICE
无论如何,我不知道为什么g++会生成愚蠢的setbe/testb序列来进行比较。这可能是您的gcc版本中的错误。如果它为其处理C++生成了正确的代码,则C++版本的速度将相同或更快。 - R.. GitHub STOP HELPING ICE
@R.. gcc中并没有“bug”,但代码肯定不是最好的。我是否遗漏了什么,或者每个人都没有开启优化?由于它什么也没做,所以循环应该被优化器完全消除。如果您不打开优化器,则不能抱怨代码,时间仅供娱乐。 - greggo

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接