我也说说宏定义likely()和unlikely()

简介:
作者:gfree.wind@gmail.com
博客:blog.focus-linux.net   linuxfocus.blog.chinaunix.net
 
 
本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
======================================================================================================
虽然不是内核工程师,但是也经常使用这两个宏,不过一直没有深究。刚才看了Bean_lee评论了一篇关于likely()和unlikely()的文章,于是也过去凑了个热闹。

该文章前面没有什么问题,我也不再重复,但是最后有个错误。“ 另外有一点要注意的是,由于likely定义时用的常量是1,unlikely用的常量是0,这正好符合c/c++语言中bool变量的实际值,而_builtin_expect()函数对exp与c进行严格相等的比较的,
因此使用likely和unlikely时,其参数应该只使用逻辑表达式,因为逻辑表达式的值只有0或1。除非真要判断某个变量的值是1或0时,才会将其它类型的参数传给likely或unlikely。这一点可能很多人会不小心用错。 ”,引自: http://blog.chinaunix.net/space.php?uid=24708340&do=blog&id=3047035

我看到这段文字时,吓了一跳。我使用likely和unlikely时从来没注意过参数非得是逻辑表达式的值啊,即0和1。难道都用错了。。。想了一下 ,就知道该博主想错了。

当使用likely和unlikely的时候,参数可以为任何表达式。不是逻辑表达式没有关系,绝不会有错。我来解释一下:
  1. #define likely(x) __builtin_expect(!!(x),1)
  2. #define unlikely(x) __builtin_expect(!!(x),0)
这是likely和unlikely的定义。看一眼定义,!!(x)这个用法就会让人觉得奇怪,为什么要!!呢?否定的否定,不就是肯定吗?干嘛多此一举呢?这就是一个技巧,学习kernel的时候,可以学到不少类似的技巧。

按照__builtin_expect的定义,要用第一个参数和第二个参数比较,它期望的值是true。第二个值是1。这里的!!(x)就是为了保证当x本身作为逻辑值为true的时候,其!!(x)值为1。举个简单的例子:
  1. if (likely(5)) {
  2.     printf("Hit!\n");
  3. }
  4. else {
  5.     printf("Not hit\n");
  6. }
本身if (5)为true,因为C标准里面规定任何非0的值均为true。Ok,!(5)为0,而!!(5)为1。这就是为啥likely和unlikely要使用!!(x),就为了其逻辑判断的值为1或者0。

关于为什么likely和unlikely可以提高程序的performance,我就不献丑了。给个官方的文献链接: http://kernelnewbies.org/FAQ/LikelyUnlikely

总的来说,它们是对编译器的一种指示,告诉编译器哪个分支更有可能发生,来最大的满足CPU的流水线作业。
目录
相关文章
|
17天前
|
编译器 C语言
【C语言】什么是宏定义?(#define详解)
【C语言】什么是宏定义?(#define详解)
24 0
|
4月前
宏定义和带参数的宏
宏定义和带参数的宏
21 0
|
10月前
|
存储 安全 编译器
【为什么】C++中的宏
【为什么】C++中的宏
|
11月前
|
编译器
宏定义(#define)及相关知识
宏定义(#define)及相关知识
82 0
|
12月前
|
C语言
宏定义#define的使用
宏定义#define的使用
80 0
|
编译器 C语言
常量和宏定义
一、变量 二、常量 三、定义符号常量 四、标识符(identifier) 五、字符串常量
常量和宏定义
|
Linux
我也说说宏定义likely()和unlikely()
作者:gfree.wind@gmail.com 博客:blog.focus-linux.net   linuxfocus.blog.chinaunix.net    本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载。
1784 0