2013-11-21 31 views

回答

13

這意味着您在編譯時讓編譯器做了額外的工作/分析,因此您可以在運行時獲得一些額外寶貴CPU週期的回報。可能最好用一個例子來解釋。

考慮一個循環是這樣的:

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

如果你編譯這個沒有優化,編譯器不會爲你做任何額外的工作 - 此代碼片段組件產生的將可能是文字翻譯成比較並跳轉指令。 (這不是最快的,只是最簡單的)

但是,如果使用優化編譯,編譯器可以很容易地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了。它只是說明了它的回報價值。

+0

非常酷!當你在調用函數時也有區別嗎? – kayla

+0

@TidusSmith以更深入的示例更新了答案。希望你覺得它有用。 – yamafontes

0

在生成程序集之前,大多數優化都發生在編譯器的中間表示中。你一定要看看Agner Fog的Software optimization resources。第1章手冊第8章介紹了編譯器通過實例進行的優化。

相關問題