linux 中likely與unlikely用法

2021-10-19 06:06:48 字數 1656 閱讀 5947

前言核心版本: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...