likely() 與 unlikely() 在 Linux kernel 中隨處可見,那為什么要用它們?它們之間有什么區別呢?
首先明確:
if (likely(value)) 等價于 if (value)
if (unlikely(value)) 等價于 if (value)
也就是說 likely() 和 unlikely() 從閱讀和理解的角度是一樣的。
這兩個宏在內核中定義如下:
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
這里的 __builtin_expect() 函數是 gcc(version >= 2.96) 的內建函數,提供給程序員使用的,目的是將"分支轉移"的信息提供給編譯器,這樣編譯器對代碼進行優化,以減少指令跳轉帶來的性能下降。
__builtin_expect(!!(x), 1)表示 x 的值為真的可能性更大.
__builtin_expect(!!(x), 0)表示 x 的值為假的可能性更大.
也就是說,使用 likely(),執行 if 后面的語句的機會更大,使用 unlikely(),執行 else 后面的語句機會更大一些。
通過這種方式,編譯器在編譯過程中,會將可能性更大的代碼緊跟著后面的代碼,從而減少指令跳轉帶來的性能上的下降。
這樣 cache 在預取數據時可以盡量取到真正要跑的數據,增加了 cache 的命中率。
不用對 likely 和 unlikely 感到迷惑,須要知曉的就是 if(likely(a>b)) 和 if(a>b) 在功能上是等價的。示例代碼:
#include xxx
#define unlikely(x) __builtin_exp ect(!!(x), 0)
#define likely(x) __builtin_exp ect(!!(x), 1)
int main()
{
int a=2,b=4;
if(unlikely(a<=b)){
printf("in the unlikely,is not your expecting!n");
} else {
printf("in the unlikely, is your exp ectingn");
}
if(likely(a<=b)){
printf("in the likely, is your exp ectingn");
}
return 0;
}
這樣的寫法,編譯器在對代碼進行優化時,就會知道第一個 if 判斷后,很可能跑的是 else 語句,cpu 就會先對 else 進行取址。
總之,likely 和 unlikely 的功能就是增加 cache 的命中率,提高系統執行速度。
-
Linux
+關注
關注
87文章
11310瀏覽量
209652 -
編譯器
+關注
關注
1文章
1634瀏覽量
49146
發布評論請先 登錄
相關推薦
Linux kernel內存管理模塊結構分析
![<b class='flag-5'>Linux</b> <b class='flag-5'>kernel</b>內存管理模塊結構分析](https://file.elecfans.com/web1/M00/C7/65/pIYBAF9lgGeAUz1cAAAUneLHs0k831.gif)
C語言中likely和unlikely的使用
說說android與linux有啥區別
Linux Kernel核心中文手冊
![<b class='flag-5'>Linux</b> <b class='flag-5'>Kernel</b>核心中文手冊](https://file.elecfans.com/web2/M00/48/8B/pYYBAGKhtAyATX-ZAAAfQP4h9CQ269.jpg)
Developing Linux kernel space
linux內核kernel-api
在Linux運行期間升級Linux系 統Uboot+kernel+Rootfs
![<b class='flag-5'>在</b><b class='flag-5'>Linux</b>運行期間升級<b class='flag-5'>Linux</b>系 統Uboot+<b class='flag-5'>kernel</b>+Rootfs](https://file.elecfans.com/web2/M00/49/37/poYBAGKhwI6AeMI_AAAn3t5ATsk792.png)
U-boot傳遞RAM和Linux kernel讀取RAM參數的解析
![U-boot傳遞RAM和<b class='flag-5'>Linux</b> <b class='flag-5'>kernel</b>讀取RAM參數的解析](https://file.elecfans.com/web1/M00/45/D1/pIYBAFp49vyANgCIAAEp7qYWC2E525.png)
Linux Kernel 5.2.2震撼發布!
Linux Kernel 5.6-rc7候選版本發布
Linux Kernel5.10維護周期將從2年延長至6年
Linux kernel的kretprobe機制和kprobe有何區別?
![<b class='flag-5'>Linux</b> <b class='flag-5'>kernel</b>的kretprobe機制和kprobe有何<b class='flag-5'>區別</b>?](https://file1.elecfans.com/web2/M00/8F/88/wKgZomTQRj2ALu_rAAAbujNORuk258.png)
評論