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 に答える