2016-08-17 61 views
-5

我正在研究一些浮點數字代碼,讓我感到沮喪的是O3優化(GCC 4.8.3)代碼的行爲會產生與O2情況(穩定的情況),並且如預期的那樣結束了數值災難。O2和O3優化的FP代碼之間差別很大的行爲

我看着this thread這可能是相關的,但答案沒有解決我的問題。我知道O3除了O2外,主要是內聯和循環展開。我很確定原因是由於浮點計算部分,因爲在我明確使用該部分的O2優化後,結果看起來很好。

#pragma GCC push_options 
#pragma GCC optimize ("O2") 

FP computation code (double precision) 

#pragma GCC pop_options 

所以我的問題是,什麼樣的優化O3確實可以真正使浮點計算的具體差異?

+4

它利用未定義的行爲?有更多的細節嗎? – JVApen

+4

如果'-fno-fast-math'不能解決問題,請發佈一個受影響代碼示例。 (我不認爲*'-O3'打開'-fast-math',但我可能是錯的''-ffast-math'是一種委婉的語言;它可以對浮點數進行廣泛的*點代碼。) – zwol

+0

@zwol但不符合IEEE-754的權利? – lorniper

回答

2

GCC manual:尚未

-O3

優化更多。 -O3打開由-O2指定的所有優化,並打開-finline-functions,-funswitch-loops,-fpredictive-commoning,-fgcse-after-reload,-ftree-vectorize,-fvect-cost-model, - ftree-partial-pre和-fipa-cp-clone選項。

沒有這些優化是特別不安全的。我看到的唯一優化可以改變結果是-ftree-vectorize。在某些情況下,與FPU指令相比,使用向量指令可以改變結果。例如,默認情況下,FPU對雙精度使用80位內部精度,而向量SIMD指令使用64位。一些數學函數(如sqrt)的實現也可能不同。

如果您發佈了代碼,確切的編譯器標誌和有關硬件的信息(您的CPU具有哪些SIMD指令),您將獲得更多獲得幫助的機會。

您也可以直接比較這兩種情況下生成的彙編代碼。

PS。但根據我的經驗,最可能的原因是程序中未定義的行爲。通常情況下,未初始化的變量,除以零等。確保編譯時使用高警告級別(-Wall -Wextra -Wpedantic),並使用UB Sanitizer。