当我意外地注意到用gcc编译的程序比用g ++编译的程序运行得快时,我正在使用循环控制变量的寄存器存储说明符来检查性能的改进。有人可以向我解释一下吗?可能重复:
Performance difference between gcc and g++ for C program
以下是代码:
#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
答案 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