天天看點

C++性能優化筆記-6-C++元素的效率差異-17-棧展開、NAN和INF傳播棧復原的其他情形NAN和INF的傳播

C++元素的效率差異

  • 棧復原的其他情形
  • NAN和INF的傳播

棧復原的其他情形

前面的章節描述了由異常處理使用的、稱為棧復原的機制,在異常出現時,不使用正常傳回途徑跳出函數後,由異常處理用來清理及調用所有必須的析構函數。這個機制也用在其他兩個情形裡:

  • 線上程終止時,可以使用棧復原機制。目的是檢測線程中聲明的對象是否有需要調用的析構函數。建議在終止線程前,從要求清理的函數傳回。不能确定的,

    _endthread()

    的調用會清理棧。取決于實作。
  • 在使用函數

    longjmp

    跳出一個函數時,也使用棧復原機制。盡可能避免使用

    longjmp

    。在時間因是關鍵因素的代碼中,不要依賴

    longjmp

NAN和INF的傳播

在大多數情形中,浮點錯誤會傳播到一系列計算的結果中。對于異常和錯誤陷阱,這是一個非常高效的可選方案。浮點溢出和除以 0 會産生無窮。加上或乘以無窮仍然是無窮。

INF

可能以這種方式傳播到最終結果。然而,不是所有和

INF

有關的操作都會産生

INF

的結果。特殊的例子,

INF - INF

INF / INF

會産生

NAN

(not-a-number)。

0 / 0

,一個函數的輸入超出範圍(例如,

sqrt(-1), log(-1)

)也會産生

NAN

。大多數以

NAN

為輸入的操作也會産生

NAN

的結果,是以

NAN

也會傳播到最終結果。這是一個檢測浮點錯誤的高效的方法。幾乎所有的浮點錯誤都會傳播道最終結果,以

INF

NAN

表現。

INF

NAN

的傳播沒有額外的代價,也不需要額外的代碼來追蹤。

一個

NAN

可以作為一些額外的資訊的負載。一個函數庫可以把錯誤碼放進這個負載來處理處理錯誤,這個負載也會傳播到最終結果。函數

finite()

,當參數是

NAN

INF

時會傳回

false

,當參數是正常浮點數時傳回

true

。這可以用作檢測錯誤,例如在浮點數轉成整數之前。

INF

NAN

傳播的細節可以參考nan_propagation中的"NAN propagation versus fault trapping in floating point code" 。其中也讨論了

INF

NAN

傳播失敗的情況,還有編譯器對

INF

NAN

傳播的相關優化選項。

繼續閱讀