我也说说宏定义likely()和unlikely()

简介:
作者:gfree.wind@gmail.com
博客:blog.focus-linux.net   linuxfocus.blog.chinaunix.net
 
 
本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
======================================================================================================
虽然不是内核工程师,但是也经常使用这两个宏,不过一直没有深究。刚才看了Bean_lee评论了一篇关于likely()和unlikely()的文章,于是也过去凑了个热闹。

该文章前面没有什么问题,我也不再重复,但是最后有个错误。“ 另外有一点要注意的是,由于likely定义时用的常量是1,unlikely用的常量是0,这正好符合c/c++语言中bool变量的实际值,而_builtin_expect()函数对exp与c进行严格相等的比较的,
因此使用likely和unlikely时,其参数应该只使用逻辑表达式,因为逻辑表达式的值只有0或1。除非真要判断某个变量的值是1或0时,才会将其它类型的参数传给likely或unlikely。这一点可能很多人会不小心用错。 ”,引自: http://blog.chinaunix.net/space.php?uid=24708340&do=blog&id=3047035

我看到这段文字时,吓了一跳。我使用likely和unlikely时从来没注意过参数非得是逻辑表达式的值啊,即0和1。难道都用错了。。。想了一下 ,就知道该博主想错了。

当使用likely和unlikely的时候,参数可以为任何表达式。不是逻辑表达式没有关系,绝不会有错。我来解释一下:
  1. #define likely(x) __builtin_expect(!!(x),1)
  2. #define unlikely(x) __builtin_expect(!!(x),0)
这是likely和unlikely的定义。看一眼定义,!!(x)这个用法就会让人觉得奇怪,为什么要!!呢?否定的否定,不就是肯定吗?干嘛多此一举呢?这就是一个技巧,学习kernel的时候,可以学到不少类似的技巧。

按照__builtin_expect的定义,要用第一个参数和第二个参数比较,它期望的值是true。第二个值是1。这里的!!(x)就是为了保证当x本身作为逻辑值为true的时候,其!!(x)值为1。举个简单的例子:
  1. if (likely(5)) {
  2.     printf("Hit!\n");
  3. }
  4. else {
  5.     printf("Not hit\n");
  6. }
本身if (5)为true,因为C标准里面规定任何非0的值均为true。Ok,!(5)为0,而!!(5)为1。这就是为啥likely和unlikely要使用!!(x),就为了其逻辑判断的值为1或者0。

关于为什么likely和unlikely可以提高程序的performance,我就不献丑了。给个官方的文献链接: http://kernelnewbies.org/FAQ/LikelyUnlikely

总的来说,它们是对编译器的一种指示,告诉编译器哪个分支更有可能发生,来最大的满足CPU的流水线作业。
目录
打赏
0
0
0
0
127
分享
相关文章
深入理解Linux网络——内核是如何接收到网络包的
一、相关实际问题 RingBuffer是什么,为什么会丢包 网络相关的硬中断、软中断是什么 Linux里的ksoftirqd内核线程是干什么
灵码智能体体验之路
本文记录了使用智能开发工具的入门体验。从VS Code更新、安装MCP插件到解决依赖问题(如Node.js),再到配置智能体生成代码,整个过程详细描述了遇到的问题与解决方案。例如,插件报错需安装Node.js、模型选择不当影响执行等。尽管存在一些不便,比如手动安装依赖和配置入口难找,但智能体的强大功能令人印象深刻,能够通过交互生成代码、调试并运行,甚至支持截图提问解决问题,极大地提升了开发效率,整体体验令人满意!
3186 16
实战 | Qwen2.5-VL模型目标检测(Grounding)任务领域微调教程
在目标检测领域,众多神经网络模型早已凭借其卓越的性能,实现了精准的目标检测与目标分割效果。然而,随着多模态模型的崛起,其在图像分析方面展现出的非凡能力,为该领域带来了新的机遇。多模态模型不仅能够深入理解图像内容,还能将这种理解转化为文本形式输出,极大地拓展了其应用场景。
562 29