LikelyUnlikely
在内核中常会见到下面这样的代码。
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相关推荐
- 【ELL】ell学习之__builtin_expect(likely-unlikely)
一.前述 在很多源码如Linux内核.Glib等,我们都能看到likely()和unlikely()这两个宏,通常这两个宏定义是下面这样的形式. // __builtin_expect()函数是GCC ...
- 几个常用的宏:likely和unlikely __raw_writel
在源码中,宏likely和unlikely 是这么定义的(位于include/linux/compiler.h): #define likely(x) __builtin_expect(!!(x), ...
- 我也说说宏定义likely()和unlikely()
作者:gfree.wind@gmail.com 博客:blog.focus-linux.net linuxfocus.blog.chinaunix.net 本文的copyleft归gfree ...
- __builtin_expect详解
在GTK+2.0源码中有很多这样的宏:G_LIKELY和G_UNLIKELY.比如下面这段代码: if (G_LIKELY (acat == 1)) /* allocate through magaz ...
- I/O函数 writel __raw_writel mb()/rmb()/wmb()
在邮件列表里讨论了一下writel是如何实现的,这个函数实现在操作系统层,有内存保护的情况下,往一个寄存器或者内存地址写一个数据. 在arch/alpha/kernel/io.c中有 188 void ...
- 分支预测优化之__builtin_expect
1.引言 在很多源码如Linux内核.Glib等,我们都能看到likely()和unlikely()这两个宏,通常这两个宏定义是下面这样的形式. #define likely(x) __builtin ...
- java race condition_java 多线程下race condition问题
这个问题的讨论来自内部的一个关于"多线程环境下使用Hashmap的安全问题"的讨论,HashMap多线程的问题之前已经提过一次,见之前的blog.本篇文章主要讨论多线程下race ...
- likely(x)与unlikely(x)函数,即__builtin_expect的使用
目录 1.引言 2. 函数声明 2.1. 功能描述 2.2. 参数详解 ① exp ② c 2.3. 返回值 2.4. 使用方法 3. RATIONALE(原理) 4. likely()和unlik ...
最新文章
- MySQL开发医药管理系统_java Web开发医药后台管理系统mysql版本源代码下载,支持中英文...
- 企业管理做不好的根源!「管理智慧」
- 任正非:明年至少招聘 8000 名应届生,华为人才将分为三类
- Dora.Interception,为.NET Core度身打造的AOP框架:全新的版本
- java登录界面命令_Java命令行界面(第30部分):观察
- Linux7/Redhat7/Centos7 安装Oracle 12C_系统安装_01
- 今天微信没有520红包 大家可以放心了!
- CentOS7安装VPP(FD.io)
- grub2与grub区别
- XQuery的contains函数
- tinyxml读xml
- C语言项目实践--图书管理系统
- hydra-字典暴力破解
- 计算机术语cal含义,计算机应用术语小释
- linux服务器输入法,linux中如何安装和切换输入法
- 如何对付不能卸载的杀毒软件
- Java网络编程与NIO详解14:Tomcat 常见面试题汇总
- php里面substr函数,PHP substr()函数
- 离散数学:n元素上的各种关系数目推导
- 分位数Quantiles
热门文章
- android miui优化,现在的小米手机怎么优化MIUI
- 蚂蚁、字节、滴滴面试经历总结
- 什么是Docker, 为什么这么火
- 除了成本低、获客快等,企业直播还有什么优势呢?
- 金融企业如何通过直播营销来获客?
- 流动电影放映服务器维修,流动数字电影放映机的日常操作与维护
- UEFI无法进入WIN10的系统?BIOS找不到ssd硬盘?reboot and select proper boot device的另一种解决思路
- 美泰推出首款获CarbonNeutral(R)认证的Matchbox(R) Tesla Roadster压铸模型车,使用99%的回收材料制作,彰显品牌的发展蓝图
- 商业虚拟专用网络技术四数据传输安全技术
- RSI指标的原理和计算方法