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范围内了。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值