我在2009年首先注意到GCC(至少在我的项目和我的机器上)如果我优化尺寸(-Os)而不是速度(-O2或-O3),则会产生明显更快的代码,我一直想知道为什么.
我设法创建(相当愚蠢)代码,显示这种令人惊讶的行为,并且足够小,无法在此处发布.
const int LOOP_BOUND = 200000000;
__attribute__((noinline))
static int add(const int& x, const int& y) {
return x + y;
}
__attribute__((noinline))
static int work(int xval, int yval) {
int sum(0);
for (int i=0; i<LOOP_BOUND; ++i) {
int x(xval+sum);
int y(yval+sum);
int z = add(x, y);
sum += z;
}
return sum;
}
int main(int , char* argv[]) {
int result = work(*argv[1], *argv[2]);
return result;
}
Run Code Online (Sandbox Code Playgroud)
如果我用-Os它编译它,执行这个程序需要0.38秒,如果用-O2 …
给定以下C函数:
void go(char *data) {
char name[64];
strcpy(name, data);
}
Run Code Online (Sandbox Code Playgroud)
x86-64上的GCC 5和6编译(简单gcc -c -g -o后跟objdump)到:
0000000000000000 <go>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 50 sub $0x50,%rsp
8: 48 89 7d b8 mov %rdi,-0x48(%rbp)
c: 48 8b 55 b8 mov -0x48(%rbp),%rdx
10: 48 8d 45 c0 lea -0x40(%rbp),%rax
14: 48 89 d6 mov %rdx,%rsi
17: 48 89 c7 mov %rax,%rdi
1a: e8 00 00 00 00 callq 1f <go+0x1f> …Run Code Online (Sandbox Code Playgroud) 在 OSX 64 位上,编译一个像这样的虚拟 C 程序:
#include <stdio.h>
void foo1() {
}
void foo2() {
}
int main() {
printf("Helloooo!\n");
foo1();
foo2();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
生成以下 ASM 代码(使用 otool 反汇编二进制文件):
(__TEXT,__text) section
_foo1:
0000000100000f10 55 pushq %rbp
0000000100000f11 4889e5 movq %rsp, %rbp
0000000100000f14 897dfc movl %edi, -0x4(%rbp)
0000000100000f17 5d popq %rbp
0000000100000f18 c3 retq
0000000100000f19 0f1f8000000000 nopl (%rax)
_foo2:
0000000100000f20 55 pushq %rbp
0000000100000f21 4889e5 movq %rsp, %rbp
0000000100000f24 5d popq %rbp
0000000100000f25 c3 retq
0000000100000f26 662e0f1f840000000000 nopw %cs:(%rax,%rax)
_main: …Run Code Online (Sandbox Code Playgroud)