在内核中常会见到下面这样的代码。

bvl = bvec_alloc(gfp_mask, nr_iovecs, &idx);
if (unlikely(!bvl)) {  mempool_free(bio, bio_pool);
  bio = NULL;
  goto out;
}
 

这个likely()和unlikely()其实是宏定义。原始定义在 include/linux/compiler.h中,如下:

#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x)     __builtin_expect(!!(x), 0)

__builtin_expect是GCC内建的函数。下面引用linuxform中的一篇讲GCC扩展文章

的一部分(原我找到的也是引用的文章,此处给出链接),里面解释得很清楚。

——————————————————- * __builtin_expect(EXP, C)  内建函数 __builtin_expect 用于为编译器提供分支预测信息,其返回值是整数表达式 EXP
的值,C 的值必须是编译时常数。例如: ++++ include/linux/compiler.h 13: #define likely(x) __builtin_expect((x),1) 14: #define unlikely(x) __builtin_expect((x),0) ++++ kernel/sched.c 564: if (unlikely(in_interrupt())) { 565: printk(”Scheduling in interruptn”); 566: BUG(); 567: }  这个内建函数的语义是 EXP 的预期值是 C,编译器可以根据这个信息适当地重排 语句块的顺序,使程序在预期的情况下有更高的执行效率。上面的例子表示处于中 断上下文是很少发生的,第 565-566 行的目标码可能会放在较远的位置,以保证 经常执行的目标码更紧凑。 ——————————————————-

总结,这个宏主要是优化的作用。如果英文好的话可以看文章一开始给出的

在kernelnewbies中的链接,那里有更详细的解说。


细心的人应该留意到有一点不同,likely()一开始偶给的定义为__builtin_expect(!!(x),1)。


后来的文章解说中成了__builtin_expect((x),1)。


这应该是后来的版本更改所至。就是新近版本的内核已经更改成__builtin_expect(!!(x),1).


加上个“!!”有什么好处哩。我想是因为使代码强壮与兼容的原因。因为不能保证x表达式的结果一定是1或0,有可能是非0数。加了“!!”,结果就一定是在1和0范围内了。

LikelyUnlikely相关推荐

  1. 【ELL】ell学习之__builtin_expect(likely-unlikely)

    一.前述 在很多源码如Linux内核.Glib等,我们都能看到likely()和unlikely()这两个宏,通常这两个宏定义是下面这样的形式. // __builtin_expect()函数是GCC ...

  2. 几个常用的宏:likely和unlikely __raw_writel

    在源码中,宏likely和unlikely 是这么定义的(位于include/linux/compiler.h): #define likely(x) __builtin_expect(!!(x), ...

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

    作者:gfree.wind@gmail.com 博客:blog.focus-linux.net   linuxfocus.blog.chinaunix.net    本文的copyleft归gfree ...

  4. __builtin_expect详解

    在GTK+2.0源码中有很多这样的宏:G_LIKELY和G_UNLIKELY.比如下面这段代码: if (G_LIKELY (acat == 1)) /* allocate through magaz ...

  5. I/O函数 writel __raw_writel mb()/rmb()/wmb()

    在邮件列表里讨论了一下writel是如何实现的,这个函数实现在操作系统层,有内存保护的情况下,往一个寄存器或者内存地址写一个数据. 在arch/alpha/kernel/io.c中有 188 void ...

  6. 分支预测优化之__builtin_expect

    1.引言 在很多源码如Linux内核.Glib等,我们都能看到likely()和unlikely()这两个宏,通常这两个宏定义是下面这样的形式. #define likely(x) __builtin ...

  7. java race condition_java 多线程下race condition问题

    这个问题的讨论来自内部的一个关于"多线程环境下使用Hashmap的安全问题"的讨论,HashMap多线程的问题之前已经提过一次,见之前的blog.本篇文章主要讨论多线程下race ...

  8. likely(x)与unlikely(x)函数,即__builtin_expect的使用

    目录 1.引言 2. 函数声明 2.1. 功能描述 2.2. 参数详解 ① exp  ② c 2.3. 返回值 2.4. 使用方法 3. RATIONALE(原理) 4. likely()和unlik ...

最新文章

  1. MySQL开发医药管理系统_java Web开发医药后台管理系统mysql版本源代码下载,支持中英文...
  2. 企业管理做不好的根源!「管理智慧」
  3. 任正非:明年至少招聘 8000 名应届生,华为人才将分为三类
  4. Dora.Interception,为.NET Core度身打造的AOP框架:全新的版本
  5. java登录界面命令_Java命令行界面(第30部分):观察
  6. Linux7/Redhat7/Centos7 安装Oracle 12C_系统安装_01
  7. 今天微信没有520红包 大家可以放心了!
  8. CentOS7安装VPP(FD.io)
  9. grub2与grub区别
  10. XQuery的contains函数
  11. tinyxml读xml
  12. C语言项目实践--图书管理系统
  13. hydra-字典暴力破解
  14. 计算机术语cal含义,计算机应用术语小释
  15. linux服务器输入法,linux中如何安装和切换输入法
  16. 如何对付不能卸载的杀毒软件
  17. Java网络编程与NIO详解14:Tomcat 常见面试题汇总
  18. php里面substr函数,PHP substr()函数
  19. 离散数学:n元素上的各种关系数目推导
  20. 分位数Quantiles

热门文章

  1. android miui优化,现在的小米手机怎么优化MIUI
  2. 蚂蚁、字节、滴滴面试经历总结
  3. 什么是Docker, 为什么这么火
  4. 除了成本低、获客快等,企业直播还有什么优势呢?
  5. 金融企业如何通过直播营销来获客?
  6. 流动电影放映服务器维修,流动数字电影放映机的日常操作与维护
  7. UEFI无法进入WIN10的系统?BIOS找不到ssd硬盘?reboot and select proper boot device的另一种解决思路
  8. 美泰推出首款获CarbonNeutral(R)认证的Matchbox(R) Tesla Roadster压铸模型车,使用99%的回收材料制作,彰显品牌的发展蓝图
  9. 商业虚拟专用网络技术四数据传输安全技术
  10. RSI指标的原理和计算方法