优化代码时,编译器在汇编时会做什么?即-O2标志 [英] What does the compiler do in assembly when optimizing code? ie -O2 flag
问题描述
因此,当您在编译C ++时添加优化标志时,它运行得更快,但这如何工作?有人可以解释一下组装中真正发生了什么吗?
So when you add an optimization flag when compiling your C++, it runs faster, but how does this work? Could someone explain what really goes on in the assembly?
推荐答案
这意味着您正在使编译器在编译时进行额外的工作/分析,因此您可以从中获得收益在运行时几个额外的宝贵CPU周期。最好用一个例子来解释。
It means you're making the compiler do extra work / analysis at compile time, so you can reap the rewards of a few extra precious cpu cycles at runtime. Might be best to explain with an example.
考虑这样的循环:
const int n = 5;
for (int i = 0; i < n; ++i)
cout << "bleh" << endl;
如果在没有优化的情况下进行编译,则编译器将不会为您做任何额外的工作-生成汇编对于此代码段,很可能是对比较和跳转指令的字面翻译。 (不是最快的,只是最简单的)
If you compile this without optimizations, the compiler will not do any extra work for you -- assembly generated for this code snippet will likely be a literal translation into compare and jump instructions. (which isn't the fastest, just the most straightforward)
但是,如果使用优化进行编译,则编译器可以轻松地内联
此循环,因为它知道上限永远不会更改,因为 n
是 const
。 (即,它可以直接复制重复的代码5次,而无需比较/检查终止循环条件)。
However, if you compile WITH optimizations, the compiler can easily inline
this loop since it knows the upper bound can't ever change because n
is const
. (i.e. it can copy the repeated code 5 times directly instead of comparing / checking for the terminating loop condition).
这里是另一个优化函数调用的示例。以下是我的整个程序:
Here's another example with an optimized function call. Below is my whole program:
#include <stdio.h>
static int foo(int a, int b) {
return a * b;
}
int main(int argc, char** argv) {
fprintf(stderr, "%d\n", foo(10, 15));
return 0;
}
如果我使用 gcc foo编译此代码而没有优化.c
在我的x86机器上,我的程序集看起来像这样:
If i compile this code without optimizations using gcc foo.c
on my x86 machine, my assembly looks like this:
movq %rsi, %rax
movl %edi, -4(%rbp)
movq %rax, -16(%rbp)
movl $10, %eax ; these are my parameters to
movl $15, %ecx ; the foo function
movl %eax, %edi
movl %ecx, %esi
callq _foo
; .. about 20 other instructions ..
callq _fprintf
这里,它没有优化任何内容。它使用我的常量值加载寄存器,并调用我的 foo
函数。但是看看我是否用 -O2
标志重新编译:
Here, it's not optimizing anything. It's loading the registers with my constant values and calling my foo
function. But look if i recompile with the -O2
flag:
movq (%rax), %rdi
leaq L_.str(%rip), %rsi
movl $150, %edx
xorb %al, %al
callq _fprintf
编译器非常聪明,它甚至不调用 foo
不再。它只是内联它的返回值。
The compiler is so smart that it doesn't even call foo
anymore. It just inlines it's return value.
这篇关于优化代码时,编译器在汇编时会做什么?即-O2标志的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!