优化代码时,编译器在汇编时会做什么?即-O2标志 [英] What does the compiler do in assembly when optimizing code? ie -O2 flag

查看:97
本文介绍了优化代码时,编译器在汇编时会做什么?即-O2标志的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,当您在编译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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆