likelly()和unlikely()详解

参考文档:
https://www.cnblogs.com/cdwodm/p/4448773.html
https://blog.csdn.net/npy_lp/article/details/7175517
Linux内核设计与实现

gcc内建了一条指令用于优化,在一个条件经常出现,或者该条件很少出现的时候,编译器可以根据这条指令对条件分支选择进行优化。内核把这条指令封装成了宏,比如likely()和unlikely() ,宏定义如下:

/* linux-2.6.38.8/include/linux/compiler.h */
# define likely(x)	__builtin_expect(!!(x), 1)
# define unlikely(x)	__builtin_expect(!!(x), 0)

在Linux内核中可以经常看到以下类似的代码块:

if (unlikely(error)) {
    /*...*/
}
else {
	/*...*/
}
if (likely(success)) {
    /*...*/
}
else {
	/*...*/
}

在代码块中,在if条件判断语句中使用unlikely()函数表示写这个程序的人认为error的值在大部分情况下都为假(0),gcc编译器识别到unlikely()函数后,会将条件判断为假执行的代码块(也就是else中的代码)放到紧跟前面的程序位置。换句话说,else下的代码放在了if下的代码的前面,因为if条件判断中大部分情况为假嘛,所以把条件为假的代码块放在前面,可以在大部分情况下先执行else下的代码,以提高程序运行的效率,达到优化性能的目的。
同样的,在if条件判断语句中使用likely()函数表示写这个程序的人认为success的值在大部分情况下都为真(1),gcc编译器识别到likely函数后,会将条件看判断为真的代码块(也就是if中的代码)放到紧跟前面的程序位置。同理可以达到优化性能的目的。

那么,搞清楚likely()和unlikely()函数的作用后,__builtin_expect函数是什么?
__builtin_expect函数是GCC编译器内置的函数,用于对条件选择语句进行优化。函数原型如下:

long  __builtin_expect (long exp, long c)
  • exp是一个表达式
  • c是期望值,必须为常量
  • 返回值是exp的值,它应该是一个整数表达式。内置的语义是期望 exp == c,就是说希望exp的值跟c的值一样,因为编译器将以c的值作为条件所执行的代码块优化到前面(紧跟前一条程序代码)。

用一个程序来测试__builtin_expect 函数的作用:

#include <stdio.h>
 
int main(void)
{
    int a;
    for(a=0;a<5;a++)
    {
    	if(__builtin_expect(a, 4))
			printf("if: a = %d,builtin_expect=%d\n", a, __builtin_expect(a, 4));
   		else
			printf("else: a = %d,builtin_expect=%d\n", a, __builtin_expect(a, 4));
	}
 
    return 0;
}

结果为:
Alt
可以看到只有当a==0时,才执行else中的代码,其余情况全部执行的是if中的代码。也就说明__builtin_expect函数返回值是exp表达式的值。
结合likely()和unlikely()的宏定义来看,likely(value)中value的值只有为真时会加快代码的执行效率(条件为真所执行的代码块放在最前面的,会最先执行),value的值为假,就会先跳过为真的代码,执行条件为假的代码,这多了一个程序跳转的步骤。同理,对于unlikely()函数是一样的道理。所以,exp == c条件成立的机会占绝大多数,那么性能将会得到提升,否则性能反而会下降。
因此,程序员对于value的值的预估必须要准确,如果判断正确,确实是这个条件占压倒性的地位,那么性能会得到提升;如果你搞错了,性能反而会下降。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值