核心中的likely和unlikely巨集的使用
在核心程式碼中經常會看到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的命中率,提高系統執行速度。
轉自:http://www.hackline.net/a/Special/Linux/shell/2009/1221/2345.html