本文轉載自:http://blog.csdn.net/npy_lp/article/details/7175517
內核源碼:Linux-2.6.38.8.tar.bz2
參考文檔:http://gcc.gnu.org/onlinedocs/gcc-4.6.2/gcc/Other-Builtins.html#Other-Builtins
在linux內核中likely和unlikely函數有兩種(只能兩者選一)實現方式,它們的實現原理稍有不同,但作用是相同的,下面將結合linux-2.6.38.8版本的內核代碼來進行講解。
1、對__builtin_expect的封裝
它們的源代碼如下:
- /* 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,如下面的例子:
- #include <stdio.h>
- int main(void)
- {
- int a;
- scanf("%d", &a);
- if(__builtin_expect(a, 4))
- printf("if: a = %d\n", a);
- else
- printf("else: a = %d\n", a);
- return 0;
- }
分別輸入整數0到4來進行5次測試,它們的輸出分別為:
- 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__函數
它們的源代碼如下:
- /* 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,如下面的例子:
- #include <stdio.h>
- #include <stdlib.h>
- #define VALUE 5
- int main(void)
- {
- char *ptr = NULL;
- int num, count;
- ptr = malloc(20);
- num = __builtin_constant_p(ptr) ? 20 : 20 + 10;
- printf("num = %d\n", num);
- free(ptr);
- count = __builtin_constant_p(VALUE) ? 20 + VALUE : 10;
- printf("count = %d\n", count);
- return 0;
- }
例子的輸出結果:
- num = 30
- count = 25
例子中的ptr為指針變量,所以__builtin_constant_p(ptr)的值為0,num的值為30。
(2)、函數__branch_check__的實現
- /* linux-2.6.38.8/include/linux/compiler.h */
- #define __branch_check__(x, expect) ({ \
- int ______r; \
- static struct ftrace_branch_data \
- __attribute__((__aligned__(4))) \
- __attribute__((section("_ftrace_annotated_branch"))) \
- ______f = { \
- .func = __func__, \
- .file = __FILE__, \
- .line = __LINE__, \
- }; \
- ______r = likely_notrace(x); \
- ftrace_likely_update(&______f, ______r, expect); \
- ______r; \
- })
使用它來檢查判斷條件並記錄likely判斷的預測信息,之后根據預測信息進行相應的優化以提升性能。
函數__branch_check__的返回值為______r的值,也就是參數x的值。