GCC(和鏘也),提供這種__builtin_expect
人類輔助的分支預測,如所解釋here。非正式地,人們用以下方式解釋它的語義:「編譯器只是無條件地處理指定的分支,如果條件應該與所示不同,則會發生昂貴的回滾」。可以使用`__builtin_expect`來影響程序語義嗎?
但是,如果我有一段代碼如下所示:
if (__builtin_expect(p != 0, 1)) // line 1
p->access_object(); // line 2
如果我處理的非正式解釋上述字面上,編譯器可以只執行第2行,而不在第1行等待條件的計算,因此如果指針碰巧爲null,則會導致未定義的行爲(空指針取消引用)。
我的問題是,如果我使用__builtin_expect
我仍然得到了保證,我的防守檢查工作?如果是這樣,如果我使用__builtin_expect
作爲上述防禦性檢查,是否可以獲得任何運行時間的好處?
(注:我使用__builtin_expect
這樣的目標是獲得的情況下,p
非空的最高性能,在放緩(甚至數量級)的情況下,p
是空的費用;即便後一種情況下會出現相當頻繁。)
IMO這是一個不好的非正式描述,據我所知,它只是優化了哪個分支,你告訴它。而這種信念似乎是由[回答一個相關的問題]備份(http://stackoverflow.com/q/7346929/583833) – Borgleader
@Borgleader:所以這個說,首先檢查執行反正。唯一的問題是執行檢查後可以立即執行,還是檢查後的一段時間。我是否正確? – Andrzej
我想說編譯器不會「無條件地處理指定的分支」。它*開始*無條件地處理它,但如果選擇了錯誤的分支則丟棄任何結果。這種丟棄發生在非常低的水平上。在條件被檢查之前,這些無條件計算的結果甚至不會在實際RAM中結束。另外,就我所知,即使沒有'__builtin_expect',在檢查條件之前總會選擇其中一個分支,但是它會被分支預測變量而不是你選擇。 – HolyBlackCat