linux内核中的预取算法,linux内核中的likely()和unlikly()

本文介绍了Linux内核中常用的likely()和unlikely()宏,它们利用__builtin_expect进行分支预测,以优化CPU预取,解释了这两个宏的工作原理及在代码中的实际应用。通过例子展示了如何影响代码执行效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

linux内核中的likely()和unlikly()

(2012-12-24 16:51:24)

标签:

linux

源码

likely()

unlikely

看内核时总遇到if(likely(

)){}或是if(unlikely( ))这样的语句,最初不解其意,现在有所了解,所以也想介绍一下。

likely() 与

unlikely()是内核(我看的是2.6.22.6版本,2.6的版本应该都有)中定义的两个宏。位于/include/linux/compiler.h中,

具体定义如下:

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

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

__builtin_expect是gcc(版本>=2.96,网上写的,我没验证过)中提供的一个预处理命令(这个名词也是网上写的,我想叫函数更好些),有利于代码优化。gcc(version

4.4.0)具体定义如下:

long __builtin_expect (long exp, long c) [Built-in Function]

注解为:

You may use __builtin_expect to provide the compiler with branch

prediction information. In general, you should prefer to use actual

profile feedback for this (‘-fprofile-arcs’), as programmers are

notoriously bad at predicting how their programs actually perform.

However, there are applications in which this data is hard to

collect.The return value is the value of exp, which should be an

integral expression. The semantics of the built-in are that it is

expected that exp == c.

它的意思是:我们可以使用这个函数人为告诉编绎器一些分支预测信息“exp==c” 是“很可能发生的”。

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

1)也就是说明x==1是“经常发生的”或是“很可能发生的”。

使用likely ,执行if后面语句的可能性大些,编译器将if{}是的内容编译到前面, 使用unlikely

,执行else后面语句的可能性大些,编译器将else{}里的内容编译到前面。这样有利于cpu预取,提高预取指令的正确率,因而可提高效率。

举个例子(内核版本2.6.22.6):/kernel/shed.c中有一段:

if (likely(!active_balance)) {

sd->balance_interval =

sd->min_interval;

} else {

if (sd->balance_interval max_interval)

sd->balance_interval *= 2;

}

编译过程中,会将if后面{}里的内容编译到前面,else 后面{}里的内容编译到后面。若将likely换成unlikely

则正好相反。

总之,likely与unlikely互换或不用都不会影响程序的正确性。但可能会影响程序的效率。

if(likely(foo))

//认为foo通常为1

if(unlikely(foo))

//认为foo通常为0

感谢各位光顾!

不知道有没有写清楚,望指正!

疑惑:

为什么likely或是unlikely要定义成__builtin_expect(!!(x),

1),而不直接用__builtin_expect(x, 1)?" !!(x) "与" x "有什么不同?

另外内核2.6.31.5中likely和unlikely还有一种定义:

# ifndef likely

# define likely(x) (__builtin_constant_p(x) ? !!(x) :

__branch_check__(x, 1))

# endif

# ifndef unlikely

# define unlikely(x) (__builtin_constant_p(x) ? !!(x) :

__branch_check__(x, 0))

# endif

原文来自:http://blog.youkuaiyun.com/tommy_wxie/article/details/7384641

分享:

a4c26d1e5885305701be709a3d33442f.png喜欢

0

a4c26d1e5885305701be709a3d33442f.png赠金笔

加载中,请稍候......

评论加载中,请稍候...

发评论

登录名: 密码: 找回密码 注册记住登录状态

昵   称:

评论并转载此博文

a4c26d1e5885305701be709a3d33442f.png

发评论

以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值