Chinaunix首页 | 论坛 | 博客
  • 博客访问: 89309
  • 博文数量: 30
  • 博客积分: 165
  • 博客等级: 入伍新兵
  • 技术积分: 237
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-05 11:35
文章分类
文章存档

2013年(5)

2012年(25)

我的朋友

分类: LINUX

2012-09-14 15:15:16

 在Linux内核中likely和unlikely函数有两种(只能两者选一)实现方式,它们的实现原理稍有不同,但作用是相同的,下面将结合linux-2.6.38.8版本的内核代码来进行讲解。

    1、对__builtin_expect的封装

    它们的源代码如下: 

  1. /* linux-2.6.38.8/include/linux/compiler.h */  
  2. # define likely(x)  __builtin_expect(!!(x), 1)   
  3. # define unlikely(x)    __builtin_expect(!!(x), 0)  
/* 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,如下面的例子: 

  1. #include    
  2.   
  3. int main(void)  
  4. {  
  5.     int a;  
  6.   
  7.     scanf("%d", &a);  
  8.   
  9.     if(__builtin_expect(a, 4))  
  10.     printf("if: a = %d\n", a);  
  11.     else  
  12.     printf("else: a = %d\n", a);  
  13.   
  14.     return 0;  
  15.      分别输入整数0到4来进行5次测试,它们的输出分别为: 
  1. else: a = 0  
  2.   
  3. if: a = 1  
  4.   
  5. if: a = 2  
  6.   
  7. if: a = 3  
  8.   
  9. if: a = 4  

 

    注意,在上例中只有输入整数0的时候才执行else后的打印语句,也就是说__builtin_expect(a, 4)函数的值就是表达式a的值。

    记住,它们只是用来提升性能的优化手段,并不会改变原来表达式的值。

    2、使用__branch_check__函数

    它们的源代码如下: 

  1. /* linux-2.6.38.8/include/linux/compiler.h */  
  2. # ifndef likely   
  3. #  define likely(x) (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 1))   
  4. # endif   
  5. # ifndef unlikely   
  6. #  define unlikely(x)   (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0))   
  7. # endif  
/* 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,如下面的例子:

  1. #include    
  2. #include    
  3.   
  4. #define VALUE 5   
  5.   
  6. int main(void)  
  7. {  
  8.     char *ptr = NULL;  
  9.     int num, count;  
  10.   
  11.     ptr = malloc(20);  
  12.     num = __builtin_constant_p(ptr) ? 20 : 20 + 10;  
  13.     printf("num = %d\n", num);  
  14.     free(ptr);  
  15.   
  16.     count = __builtin_constant_p(VALUE) ? 20 + VALUE : 10;  
  17.     printf("count = %d\n", count);  
  18.   
  19.     return 0;  
  20. }  
#include #include #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; }

    例子的输出结果: 

  1. num = 30  
  2. count = 25  
num = 30 count = 25

    例子中的ptr为指针变量,所以__builtin_constant_p(ptr)的值为0,num的值为30。

    (2)、函数__branch_check__的实现 

  1. /* linux-2.6.38.8/include/linux/compiler.h */  
  2. #define __branch_check__(x, expect) ({                  \   
  3.             int ______r;                    \  
  4.             static struct ftrace_branch_data        \  
  5.                 __attribute__((__aligned__(4)))     \  
  6.                 __attribute__((section("_ftrace_annotated_branch"))) \  
  7.                 ______f = {             \  
  8.                 .func = __func__,           \  
  9.                 .file = __FILE__,           \  
  10.                 .line = __LINE__,           \  
  11.             };                      \  
  12.             ______r = likely_notrace(x);            \  
  13.             ftrace_likely_update(&______f, ______r, expect); \  
  14.             ______r;                    \  
  15.         })  
/* 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的值。

阅读(1300) | 评论(0) | 转发(0) |
0

上一篇:USB详解

下一篇:Run-time PM 详解

给主人留下些什么吧!~~