我创建了这段代码:
#include <stdio.h>
typedef unsigned int uint;
uint in[2]={1,2},out[2]={3,4};
int main() {
in[0]=out[0]/10;
}
并在Linux上使用GCC(v4.4.5,无优化)编译它,生成的程序集是:
0000000000400474 <main>:
400474: 55 push rbp
400475: 48 89 e5 mov rbp,rsp
400478: 8b 05 ae 03 20 00 mov eax,DWORD PTR [rip+0x2003ae] # 0082c <out>
40047e: 89 45 fc mov DWORD PTR [rbp-0x4],eax
400481: ba cd cc cc cc mov edx,0xcccccccd
400486: 8b 45 fc mov eax,DWORD PTR [rbp-0x4]
400489: f7 e2 mul edx
40048b: 89 d0 mov eax,edx
40048d: c1 e8 03 shr eax,0x3
400490: 89 05 8e 03 20 00 mov DWORD PTR [rip+0x20038e],eax # 600824 <in>
400496: c9 leave
400497: c3 ret
400498: 90 nop
400499: 90 nop
40049a: 90 nop
40049b: 90 nop
40049c: 90 nop
40049d: 90 nop
40049e: 90 nop
40049f: 90 nop
现在,问题是:这个代码在第5行上做了什么?
40047e: 89 45 fc mov DWORD PTR [rbp-0x4],eax
是不是在内存中的某个地方再次存储了从[0]中获取的值?为什么这样?我没有告诉它立即读取和写入某个位置。
现在,这个时间变量再次出现在第7行的地址400486上:
400486: 8b 45 fc mov eax,DWORD PTR [rbp-0x4]
在这个示例中看起来GCC正在生成效率非常低的代码,并且由于这些临时存储,它将逐出高速缓存行。请确认,也许有一些我没有得到的东西。
答案 0 :(得分:5)
在-O0
上编译时,GCC会生成效率非常低的代码 - 您所看到的内容基本上是其内部代表程序的原始翻译。此内部表示包含许多临时变量,此处的加载/存储对是通过此类临时值的值。在更高的优化级别上,这些无用的装载/存储将大部分被消除;但是在-O0
上,即使最简单的分析也被禁用。