在Linux內核代碼中經常看到likely()和unlikely()這兩個宏,其定義如下:
# define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0)
其中__builtin_expect()函數是gcc提供的用於對分支語句進行優化,其原型如下:
long __builtin_expect (long exp, long c)
當exp == c時,該函數返回非零值;
gcc內建這個函數用於條件選擇語句的優化,在一個條件經常出現,或者該條件很少出現的時候,編譯器可以對條件分支選擇進行優化;likely(x)即表示x很可能或者絕大多數情況下為真;而unlikely則剛好相反。(宏定義中的!!(x),對x兩次取反,只是確保將x轉化成bool型)
如對下面的條件選擇語句:
if (error) {
......
}
如果想把這個標記成絕少發生的分支,即認為error絕大多數情況下都為0:
if (unlikely(error)) {
......
}
相反,如果認為某個分支發生的可能性很大:
if (likely(success)) {
......
}
即認為success在絕大多數情況下為真。
在對某個條件選擇語句進行優化之前,一定要搞清楚其中是不是存在這麼一個條件,在絕大多數情況下都會成立;如果判斷正確,那麼性能會提高,否則將會產生相反的效果。(編譯器在碰到需要優化的條件分支時,會將可能性大的分支編譯到前面來,這樣有利於CPU的預取,提高預取指令的正確率,從而提高性能)
Linux Kernel 的詳細介紹:請點這裡
Linux Kernel 的下載地址:請點這裡