Linux-能否从汇编的角度,介绍下linux内核的likely是如何实现优化的
如题。希望能给出示例分析,以便能够得到更直观地理解。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
如题。希望能给出示例分析,以便能够得到更直观地理解。
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(1)
likely() 与 unlikely()位于/include/linux/compiler.h中(2.6.22.6版本),其定义如下:
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
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预取,提高预取指令的正确率,因而可提高效率。
参考链接:linux中 likely与unlikely
我在查看内核2.6.32版本,发现likely的定义已经发生了变化:
# 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
尝试从汇编角度分许,但能力有限,难以解释这其中的奥秘,还期待大牛的解答。
======补充
原答案已经讲了likely的功用。一看就明白,这个likely是一个只对编译器有意义的宏,导致生成的汇编代码顺序不同。
而这个和汇编代码本身没有关系(汇编中没有likely对应的相关指令),而和CPU指令缓存有关系,关于CPU缓存,刚好这有篇文章讲解:http://coolshell.cn/articles/10249.html
通过likely宏,提示编译器根据代码语义优化生成的汇编代码,将更可能被执行到的代码放到前面的位置,这样CPU指令缓存能够更多被命中。