詳解likely和unlikely函式

2021-07-11 22:51:12 字數 2475 閱讀 2675

在linux核心中likely和unlikely函式有兩種(只能兩者選一)實現方式,它們的實現原理稍有不同,但作用是相同的,下面將結合linux-2.6.38.8版本的核心**來進行講解。

1、對__builtin_expect的封裝

它們的源**如下: 

[cpp]view plain

copy

/* linux-2.6.38.8/include/linux/compiler.h */

# define likely(x)  __builtin_expect(!!(x), 1)

# define unlikely(x)    __builtin_expect(!!(x), 0)

__builtin_expect 是gcc的內建函式,用來對選擇語句的判斷條件進行優化,常用於乙個判斷條件經常成立(如likely)或經常不成立(如unlikely)的情況。

__builtin_expect的函式原型為long  __builtin_expect (long exp, long c),返回值為完整表示式exp的值,它的作用是期望表示式exp的值等於c(注意,如果exp == c條件成立的機會佔絕大多數,那麼效能將會得到提公升,否則效能反而會下降)。

在普通的應用程式中也可以使用__builtin_expect,如下面的例子: 

[cpp]view plain

copy

#include 

intmain(

void

)    

分別輸入整數0到4來進行5次測試,它們的輸出分別為: 

[cpp]view plain

copy

else

: a = 0  

if: a = 1  

if: a = 2  

if: a = 3  

if: a = 4  

注意,在上例中只有輸入整數0的時候才執行else後的列印語句,也就是說__builtin_expect(a, 4)函式的值就是表示式a的值。

記住,它們只是用來提公升效能的優化手段,並不會改變原來表示式的值。

2、使用__branch_check__函式

它們的源**如下: 

[cpp]view plain

copy

/* linux-2.6.38.8/include/linux/compiler.h */

# ifndef likely

#  define likely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 1))

# endif

# ifndef unlikely

#  define unlikely(x)   (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0))

# endif

(1)、先使用內建函式__builtin_constant_p忽略表示式x為常量的情況

__builtin_constant_p也是gcc的內建函式,函式原型為int  __builtin_constant_p(exp),用於判斷表示式exp在編譯時是否是乙個常量,如果是則函式的值為整數1,否則為0,如下面的例子:

[cpp]view plain

copy

#include 

#include 

#define value 5

intmain(

void

)    

例子的輸出結果: 

[cpp]view plain

copy

num = 30  

count = 25  

例子中的ptr為指標變數,所以__builtin_constant_p(ptr)的值為0,num的值為30。

(2)、函式__branch_check__的實現 

[cpp]view plain

copy

/* linux-2.6.38.8/include/linux/compiler.h */

#define __branch_check__(x, expect) (;                      \  

______r = likely_notrace(x);            \  

ftrace_likely_update(&______f, ______r, expect); \  

______r;                    \  

})  

使用它來檢查判斷條件並記錄likely判斷的**資訊,之後根據**資訊進行相應的優化以提公升效能。

函式__branch_check__的返回值為______r的值,也就是引數x的值。

使用likely和unlikely 優化程式效能

作用 likely unlikely是為編譯器提供對分支優化的提示,基本用於if else的分支優化場景。if else在彙編時會將else分支的命令生成跳轉語句 jmp 而跳轉會影響程式效能,所以如果大部分情況下都是else分支成立的話,程式每次都會執行跳轉,從而影響效率,使用likely和unl...

核心中的likely和unlikely巨集的使用

在核心 中經常會看到unlikely和likely的蹤影。他們實際上是定義在 linux compiler.h 中的兩個巨集。define likely x builtin expect x 1 define unlikely x builtin expect x 0 這裡的 built expec...

在linux中的likely和unlikely

在linux中的likely和unlikely 0 推薦 在linux中判斷語句經常會看到likely和unlikely,例如 if likely value else 簡單從表面上看if likely value if value if unlikely value if value 這兩個巨集對...