前言核心版本:linux 4.13
在linux核心中,經常可以看見if( likely(x))或if( unlikely(x))語句,那麼likely和unlikely是什麼意思呢?本文將對likely和unlikely進行一些討論。
likely和unlikely
參考/include/linux/compiler.h */
# define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0)
上述原始碼中採用了內建函式__builtin_expect來進行定義,即 built in function。
__builtin_expect的函式原型為long __builtin_expect (long exp, long c),返回值為完整表示式exp的值,它的作用是期望表示式exp的值等於c(如果exp == c條件成立的機會佔絕大多數,那麼效能將會得到提公升,否則效能反而會下降)。注意, __builtin_expect (lexp, c)的返回值仍是exp值本身,並不會改變exp的值。
__builtin_expect函式用來引導gcc進行條件分支**。在一條指令執行時,由於流水線的作用,cpu可以同時完成下一條指令的取指,這樣可以提高cpu的利用率。在執行條件分支指令時,cpu也會預取下一條執行,但是如果條件分支的結果為跳轉到了其他指令,那cpu預取的下一條指令就沒用了,這樣就降低了流水線的效率。
另外,跳轉指令相對於順序執行的指令會多消耗cpu時間,如果可以盡可能不執行跳轉,也可以提高cpu效能。
簡單從表面上看if(likely(value)) == if(value),if(unlikely(value)) == if(value)。
也就是likely和unlikely是一樣的,但是實際上執行是不同的,加likely的意思是value的值為真的可能性更大一些,那麼執行if的機會大,而unlikely表示value的值為假的可能性大一些,執行else機會大一些。
加上這種修飾,編譯成二進位制**時likely使得if後面的執行語句緊跟著前面的程式,unlikely使得else後面的語句緊跟著前面的程式,這樣就會被cache預讀取,增加程式的執行速度。
那麼上述定義中為什麼要使用!!符號呢?
計算機中bool邏輯只有0和1,非0即是1,當likely(x)中引數不是邏輯值時,就可以使用!!符號轉化為邏輯值1或0 。比如:!!(3)=!(!(3))=!0=1,這樣就把引數3轉化為邏輯1了。
那麼簡單理解就是:
likely(x)代表x是邏輯真(1)的可能性比較大;
unlikely(x)代表x是邏輯假(0)的可能性比較大。
總結:
當程式設計師清楚exp表示式 多數情況成立(不成立)時,就可使用likely(unlikely),使if分支(else分支)緊跟跳轉指令其後,從而在大多數情況下不用執行跳轉指令,避開跳轉指令所帶來的開銷,從而達到優化的目的。
c語言高階——likely和unlikely:
在linux中的likely和unlikely
在linux中的likely和unlikely 0 推薦 在linux中判斷語句經常會看到likely和unlikely,例如 if likely value else 簡單從表面上看if likely value if value if unlikely value if value 這兩個巨集對...
sql語法中u n 詳解
今天翻閱檢視的時候,發現sql語句中有n u 這樣的語法,不懂什麼意思,於是搜尋了一下,得出如下結論。例子 select u 中文 from dual select n 中文 from dual 那麼語句中的n以及u分別代表什麼意思?n 在這裡表示 unicode,就是雙位元組字元。對於西文字元,用...
likely 與unlikely 函式的意義
總之,likely與unlikely互換或不用都不會影響程式的正確性。但可能會影響程式的效率。if likely foo 認為foo通常為1 if unlikely foo 認為foo通常為0 感謝各位光顧!不知道有沒有寫清楚,望指正!疑惑 為什麼likely或是unlikely要定義成 built...