簡體   English   中英

來自-ffast-math的gcc鏈接器行為的奇怪結果

[英]Curious result from the gcc linker behaviour around -ffast-math

我注意到在編譯器鏈接器的標志周圍有一種有趣的現象,它以我無法理解的方式影響正在運行的代碼。

我有一個庫,提供了相同算法的不同實現,以便測試這些不同實現的運行速度。

最初,我使用一對相同的實現對情況進行了測試,以檢查是否發生了正確的事情(兩者都以大致相同的速度運行)。 我首先使用以下編譯器標志編譯對象(每個實現一個):

-g -funroll-loops -flto -Ofast -Werror

然后在鏈接中通過gcc傳遞以下標志:

-Ofast -flto=4 -fuse-linker-plugin

這提供了一個運行得非常快的庫,但是奇怪的是,對於鏈接期間包含在參數中的第一個對象,可靠且可重復地快了7%左右(因此,如果先鏈接,則實現都更快)。

因此:

gcc -o libfoo.so -O3 -ffast-math -flto=4 -fuse-linker-plugin -shared support_obj.os obj1.os obj2.os -lm

VS

gcc -o libfoo.so -O3 -ffast-math -flto=4 -fuse-linker-plugin -shared support_obj.os obj2.os obj1.os -lm

第一種情況是obj1中的實現比obj2中的實現運行得更快。 在第二種情況下,情況相反。 為了清楚起見,除了函數條目名稱之外,兩種情況下的代碼都是相同的。

現在,我通過在鏈接期間刪除-Ofast標志來消除了這種奇怪的鏈接參數順序差異(並實際上加快了一點)。

通過將-Ofast更改為-O3 -ffast-math ,我可以復制幾乎相同的情況,但是在那種情況下,我需要在鏈接期間提供-ffast-math ,這又導致了奇怪的訂購速度差異。 我不確定為什么在鏈接過程中未通過-ffast-math時為什么保持-Ofast而不是-ffast-math -ffast-math ,但是我可以接受,這可能-ffast-math傳遞相關信息的鏈接時間優化在一種情況下,但在另一種情況下,則不是。 但這並不能解釋速度差異。

刪除-ffast-math意味着它的運行速度慢了約8倍。

是否有人能夠闡明可能引起這種影響的原因? 我真的很想知道會導致這種有趣行為的原因,所以我不會偶然觸發它。

運行速度測試是使用庫和timeit周圍的包裝在python中執行的,我相當確定這是做對的事情(我可以​​旋轉命令,並且可以看出python的副作用可以忽略不計)。

我還測試了庫的輸出正確性,因此我也可以對此充滿信心。

發表評論的時間過長,因此被發布為答案:

由於存在在數學運算中獲得錯誤結果的風險,因此建議不要使用它。

使用-ffast_math和/或-Ofast可能導致錯誤的結果,如gcc手冊中的以下摘錄所示:

選項: -ffast-math設置選項:

  1. -fno-數學錯誤號,
  2. -funsafe-數學優化,
  3. -ffinite,數學只,
  4. -fno-舍入數學,
  5. -fno-signaling-nans和
  6. -fcx-有限范圍。

此選項將導致定義預處理程序宏__FAST_MATH__

-Ofast外,此選項未由任何-O選項-Ofast因為它可能導致依賴於數學函數的IEEE或ISO規則/規范的確切實現的程序輸出不正確。 但是,對於不需要這些規范保證的程序,它可能會產生更快的代碼。

選項: -Ofast

忽略嚴格的標准合規性。 -Ofast啟用所有-O3優化。 它還啟用了並非對所有符合標准的程序都有效的優化。 它打開-ffast-math和Fortran特定的-fno-protect-parens-fstack-arrays

暫無
暫無

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

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