簡體   English   中英

GCC的快速機制在跨平台或編譯器版本上是否具有一致性保證?

[英]Does GCC's ffast-math have consistency guarantees across platforms or compiler versions?

我想編寫跨平台的C / C ++,它在不同環境中的行為都可重現。

我知道gcc的快速數學可以實現各種浮點近似。 很好,但是我需要兩個單獨編譯的二進制文件才能產生相同的結果。

假設我一直使用gcc,但是對於Windows,Linux或其他任何版本,以及不同的編譯器版本,我都使用gcc。

是否可以保證這些編譯對於相同的源代碼將產生相同的浮點近似值集?

,不是它們允許特定的近似值,而是-ffast-math允許編譯器假設FP數學是關聯的,而不是。 即在轉換代碼以允許更有效的匯編時忽略舍入錯誤。

通過選擇不同的舍入,操作順序選擇上的任何細微差異都會影響結果。

較早的編譯器版本可能選擇使用-ffast-math的Newton-Raphson迭代將sqrt(x)x * approx_rsqrt(x) ,因為較舊的CPU具有較慢的sqrtps指令,因此通常更值得將其替換為reciprocal-sqrt的近似值+ 3或4更多乘和加指令。 對於最新的CPU,大多數代碼通常不是這種情況,因此, 即使您使用相同的調整選項 (尤其是默認的-mtune=generic而不是-mtune=haswell ),該選項所做的選擇也可能在GCC版本之間改變。


沒有 -ffast-math很難獲得確定性的FP 不同操作系統上的不同庫具有諸如sinlog類的功能的不同實現(與基本操作+-* / sqrt不同,不需要返回“正確舍入”的結果,即最大誤差為0.5ulp)。

如果使用x87 FP數學為32位x86進行編譯,則臨時FLT_EVAL_METHOD額外精度( FLT_EVAL_METHOD )可以更改結果。 -mfpmath=387-m32的默認值)。 如果您希望在這里有所希望,請避免使用32位x86。 或者,如果您堅持使用它,也許您可​​以使用-msse2 -mfpmath=sse ...

您提到Windows,所以我假設您只是在談論x86 GNU / Linux,即使Linux在許多其他ISA上運行也是如此。

但是,即使只是在x86內,使用-march=haswell進行編譯-march=haswell可以使用FMA指令,並且GCC缺省為#pragma STDC FP_CONTRACT ON (即使在C語句中,也超出了通常的ISO C規則所允許的范圍。)因此,即使沒有-ffast-math ,FMA可用性可以消除x*y + z x*y臨時值的舍入。


使用-ffast-math

當對數組求和時,一個版本的gcc可能決定將循環展開2(並使用2個單獨的累加器),而較舊版本的具有相同選項的gcc可能仍會按順序求和。

(實際上,當前的gcc對此很糟糕,當它展開(默認情況下不是默認狀態)時,它通常仍使用相同的(向量)累加器,因此它不會像clang那樣隱藏FP延遲。例如https://godbolt.org/ z / X6DTxK對同一變量使用不同的寄存器,但它仍然只是一個累加器,求和循環后沒有垂直加法運算 ,但希望將來的gcc版本會更好,而且gcc版本之間在如何對YMM進行水平求和方面存在差異或XMM寄存器可能在自動矢量化時在此處引入差異)

暫無
暫無

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

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