天天看点

likely和unlikely函数

likely和unlikely函数

今天看源码的时候遇到likely和unlikely两个函数,第一感觉是很困惑,1、都是在if的判断语句中,2、其中参数也都是简单的比大小等类型的判断语句,3、感觉没有likely和unlikely也可以判断,那么为啥非要加上一个“函数”呢?

于是上网查明这个likely和unlikely

快速了解:

likely和unlikely分别表明了要判断的条件很有可能会发生和不会发生。

再直白一点,

如果我们觉得一个if里的条件很大概率是真,那么我们使用likely,反之使用unlikely。

深入一点点:

likely() 与 unlikely()是内核中定义的两个宏。位于/include/linux/compiler.h中,

具体定义如下:

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

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

!!(x)有助于将x的结果变为bool,在这里与x的区别并不大(会默认转换类型)。但用于返回值的时候体现出较大的却别。如 return !!(x),这里就将原来的x的类型转换成了bool型。第二个参数1,0表示!!(x)的值的很可能为1或0。

系统编译后在汇编级的代码会有少许区别,主要会改变if语句执行的跳转(if判断为错时需要跳到下一条语句),使用__builtin_expect可以使汇编代码结构更合理,使得每次判断很大概率为真,减少了跳转。仅当小概率的事件发生时才跳转,这样减少了部分跳转语句。

同时,结合操作系统知识,我们知道计算机执行时cpu的计算速度非常快,往往要预加载一些数据(利用缓存实现,缓存读取速度很快,但成本高,一般较小),提前准备好数据,来提高cpu效率,当我们遇到一些需要判断的情况时,比如遇到if语句,由于是预加载我们只有执行了if语句才知道加载的对不对,所以可能会出现预加载的数据不对,如果加载数据不对那么就要重新加载这个过程相对cpu来说是非常耗时的。

由于cpu计算速度非常快,预加载数据是必须的,增大预加载数据的命中率是非常必要的,操作系统通常会自动优化,来提高命中率。然而系统自带的优化并不是万能的,此时我们需要给系统提供信息,改善优化,增加命中率。