[英]g++: optimization -march=haswell and newer changes numerical result
當我注意到g ++似乎根據所選優化改變結果時,我一直在努力優化性能,當然還在進行回歸測試。 到目前為止,我認為-O2 -march=[whatever]
應該為數值計算產生完全相同的結果,無論選擇何種體系結構。 然而,對於g ++來說似乎並非如此。 雖然使用舊架構到ivybridge產生與clang對任何架構相同的結果,但是對於haswell和更新的gcc,我得到了不同的結果。 這是gcc中的錯誤還是我誤解了有關優化的內容? 我真的很吃驚,因為clang似乎沒有表現出這種行為。
請注意,我很清楚差異在機器精度范圍內,但它們仍然會干擾我的簡單回歸檢查。
這是一些示例代碼:
#include <iostream>
#include <armadillo>
int main(){
arma::arma_rng::set_seed(3);
arma::sp_cx_mat A = arma::sprandn<arma::sp_cx_mat>(20,20, 0.1);
arma::sp_cx_mat B = A + A.t();
arma::cx_vec eig;
arma::eigs_gen(eig, B, 1, "lm", 0.001);
std::cout << "eigenvalue: " << eig << std::endl;
}
編譯使用:
g++ -march=[architecture] -std=c++14 -O2 -o test example.cpp -larmadillo
gcc版本:6.2.1
鏗鏘版:3.8.0
編譯為64位,在Intel Skylake處理器上執行。
這是因為GCC默認使用fusion-multiply-add(fma)指令(如果可用)。 相反,Clang默認不使用它們,即使它可用。
a*b+c
可以不同,無論是否使用fma,這就是為什么你得到不同的結果,當你使用-march=haswell
(Haswell是第一個支持fma的Intel CPU)。
您可以決定是否要將此功能與-ffp-contract=XXX
。
-ffp-contract=off
,你不會得到fma指令。 -ffp-contract=on
,你得到fma指令,但只有在語言標准允許的情況下收縮。 在當前版本的GCC中,這意味着關閉(因為它尚未實現)。 -ffp-contract=fast
(這是GCC的默認值),你會得到fma指令。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.