簡體   English   中英

優化代碼時編譯器在匯編中做了什么?即-O2標志

[英]What does the compiler do in assembly when optimizing code? ie -O2 flag

因此,當您在編譯C ++時添加優化標志時,它運行得更快,但這是如何工作的? 有人能解釋一下裝配中究竟發生了什么嗎?

這意味着您正在使編譯器在編譯時執行額外的工作/分析,因此您可以在運行時獲得一些額外的寶貴cpu周期的獎勵。 可能最好用一個例子來解釋。

考慮這樣的循環:

const int n = 5;
for (int i = 0; i < n; ++i)
  cout << "bleh" << endl;

如果你在沒有優化的情況下編譯它,編譯器將不會為你做任何額外的工作 - 為這段代碼片段生成的程序集可能是比較和跳轉指令的字面翻譯。 (這不是最快的,只是最直接的)

但是,如果編譯WITH優化,編譯器可以很容易地inline這個循環,因為它知道上限不能改變,因為nconst (即它可以直接復制重復代碼5次,而不是比較/檢查終止循環條件)。

這是另一個優化函數調用的例子。 以下是我的整個計划:

#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;
}

如果我在我的x86機器上使用gcc foo.c編譯此代碼時沒有進行優化,我的程序集如下所示:

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標志重新編譯:

movq    (%rax), %rdi
leaq    L_.str(%rip), %rsi
movl    $150, %edx
xorb    %al, %al
callq   _fprintf

編譯器非常聰明,甚至不再調用foo 它只是概述了它的回報價值。

在生成程序集之前,大多數優化都發生在編譯器的中間表示中。 您一定要查看Agner Fog的軟件優化資源 第1手冊的第8章描述了編譯器使用示例執行的優化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM