天天看點

unlikely和likely

在核心代碼中經常會看到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