現代編譯器中的優化越來越好,通過使用SIMD指令進行常量摺疊等基本優化。但是,我想知道這種優化應該在多遠以及編譯器如何做出這樣的決定。提前編譯器如何確定優化有多遠?
讓我們來看一個例子:
#include <stdio.h>
static double naive_sin(double n) {
return n - n*n*n/6.0 + n*n*n*n*n/120.0 + n*n*n*n*n*n*n/5040.0;
}
int main() {
printf("%f\n", naive_sin(1.0));
return 0;
}
當與GCC與-O3
編譯此,可以觀察到,得到的浮點數是由編譯器計算並存儲在源代碼。進一步優化顯然是不可能的。
現在,讓我們來看看第二個例子:
#include <stdio.h>
int main() {
double start = 0.0;
for (int i = 0; i < 100; i++) {
start += 1.0;
}
printf("%f\n", start);
return 0;
}
考慮到第一個例子的結果,人們可以期望編譯器採用類似的優化和所產生的機器代碼產生恆定100.0
。但是,在查看輸出時,事實證明循環仍然存在!
顯然這種優化並不總是可能的。假設你正在編寫一個計算pi的程序,達到100萬個地方。這樣的程序不需要用戶輸入,因此理論上可以通過編譯器將結果硬編碼到機器代碼中。當然,這不是一個好主意,因爲編譯器在內部評估程序時需要更長的時間,而不是僅僅運行較少優化的版本。
但是,在這種情況下,編譯器決定不優化循環的原因是什麼?有沒有優化這種代碼的語言/編譯器,或有什麼阻止這種情況?這可能與不能預測一個項目是否會結束的概念有關嗎?
「提前編譯器如何確定優化有多遠?」 - 它看起來在命令行標誌:)) – 2013-08-02 23:12:03
「無法預測程序是否會結束」是(FYI)稱爲[暫停問題](http://en.wikipedia.org/wiki/) Halting_problem)。請注意,編譯器可以並且展開一些循環,因此編譯器可以在*某些情況下證明循環將終止。 – cdhowie
這是一個非問題。 AOT處理代碼的*圖形*,它實際上不執行*代碼。程序員不會編寫無限嵌套的函數。 –