在核心代碼中經常會看到unlikely和likely的蹤影。他們實際上是定義在 linux/compiler.h 中的兩個宏。
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
這裡的__built_expect()函數是gcc的內建函數。
至于為什麼要在核心代碼中使用這兩個宏,主要的目的是為了進行代碼的優化,提高系統執行速度。
比如 :
if (likely(a>b)) {
fun1();
}
if (unlikely(a<b)) {
fun2();
}
這裡就是程式員可以确定 a>b 在程式執行過程中出現的可能相比較大,是以使用了likely()告訴編譯器将fun1()函數的二進制代碼緊跟在前面程式的後面,這樣就cache在預取資料時就可以将fun1()函數的二進制代碼拿到cache中。這樣,也就增加了cache的命中率。
同樣的,unlikely()的作用就是告訴編譯器,a<b 的可能性很小是以這裡在編譯時,将fun2()的二進制代碼盡量不要和前邊的編譯在一塊。
我們不用對likely和unlikely感到迷惑,需要知道的就是 if(likely(a>b)) 和 if(a>b)在功能上是等價的,同樣 if(unlikely(a<b)) 和 if(a<b) 的功能也是一樣的。不一樣的隻是他們聲稱的二進制代碼有所不同,這一點我們也可以從他們的彙編代碼中看到。
比如下面的代碼:
#include <stdio.h>
#define unlikely(x) __builtin_expect(!!(x), 0)
#define likely(x) __builtin_expect(!!(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 expecting\n");
}
if(likely(a<b)) {
printf("in the likely, is your expecting\n");
}
return 0;
}
執行結果:
in the unlikely,is not your expecting!
in the likely, is your expecting
總之,likely和unlikely的功能就是增加cache的命中率,提高系統執行速度。
版權聲明:本文為CSDN部落客「weixin_34250434」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。
原文連結:https://blog.csdn.net/weixin_34250434/article/details/91926727