已阅读5页,还剩3页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
关于likely()与unlikely函数 分类: 嵌入式 Linux内核 2011-11-29 19:55 378人阅读 评论(0) 收藏 举报 优化编译器gcc支声明对于条件选择语句,gcc内建了一条指令用于优化,在一个条件经常出现,或者该条件很少出现的时候,编译器可以根据这条指令对条件分支选择进行优化。内核把这条指令封装成了宏,比如likely()和unlikely(),这样使用起来比较方便。例如,下面是一个条件选择语句:if (foo) /* . */如果想要把这个选择标记成绝少发生的分支:/* 我们认为foo绝大多数时间都会为0. */if (unlikely(foo) /* . */相反,如果我们想把一个分支标记为通常为真的选择:/* 我们认为foo通常都不会为0 */if(likely(foo) /* . */ likely()与unlikely()函数的意义 2013-03-03 15:32:42 分类: 嵌入式看内核时总遇到if(likely( )或是if(unlikely( )这样的语句,最初不解其意,现在有所了解,所以也想介绍一下。likely() 与 unlikely()是内核(我看的是版本,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预取,提高预取指令的正确率,因而可提高效率。举个例子(内核版本):/kernel/shed.c中有一段:if (likely(!active_balance) /* We were unbalanced, so reset the balancing interval */sd-balance_interval = sd-min_interval; else /* If weve begun active balancing, start to back off. This* case may not be covered by the all_pinned logic if there* is only 1 task on the busy runqueue (because we dont call* move_tasks).*/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函数 分类: ARM 相关 linux内核分析 2012-06-13 23:28 784人阅读 评论(0) 收藏 举报 branchlinux内核优化gccstruct文档内核源码:linux-.tar.bz2 参考文档:/onlinedocs/gcc-4.6.2/gcc/Other-Builtins.html#Other-Builtins 在Linux内核中likely和unlikely函数有两种(只能两者选一)实现方式,它们的实现原理稍有不同,但作用是相同的,下面将结合linux-版本的内核代码来进行讲解。 1、对_builtin_expect的封装 它们的源代码如下:cpp view plaincopyprint?1. /*linux-/include/linux/compiler.h*/2. #definelikely(x)_builtin_expect(!(x),1)3. #defineunlikely(x)_builtin_expect(!(x),0) _builtin_expect是GCC的内置函数,用来对选择语句的判断条件进行优化,常用于一个判断条件经常成立(如likely)或经常不成立(如unlikely)的情况。 _builtin_expect的函数原型为long _builtin_expect(long exp, long c),返回值为完整表达式exp的值,它的作用是期望表达式exp的值等于c(注意,如果exp = c条件成立的机会占绝大多数,那么性能将会得到提升,否则性能反而会下降)。 在普通的应用程序中也可以使用_builtin_expect,如下面的例子:cpp view plaincopyprint?1. #include2. 3. intmain(void)4. 5. inta;6. 7. scanf(%d,&a);8. 9. if(_builtin_expect(a,4)10. printf(if:a=%dn,a);11. else12. printf(else:a=%dn,a);13. 14. return0;15. 分别输入整数0到4来进行5次测试,它们的输出分别为:cpp view plaincopyprint?1. else:a=02. 3. if:a=14. 5. if:a=26. 7. if:a=38. 9. if:a=4 注意,在上例中只有输入整数0的时候才执行else后的打印语句,也就是说_builtin_expect(a, 4)函数的值就是表达式a的值。 记住,它们只是用来提升性能的优化手段,并不会改变原来表达式的值。 2、使用_branch_check_函数 它们的源代码如下:cpp view plaincopyprint?1. /*linux-/include/linux/compiler.h*/2. #ifndeflikely3. #definelikely(x)(_builtin_constant_p(x)?!(x):_branch_check_(x,1)4. #endif5. #ifndefunlikely6. #defineunlikely(x)(_builtin_constant_p(x)?!(x):_branch_check_(x,0)7. #endif (1)、先使用内置函数_builtin_constant_p忽略表达式x为常量的情况 _builtin_constant_p也是GCC的内置函数,函数原型为int _builtin_constant_p(exp),用于判断表达式exp在编译时是否是一个常量,如果是则函数的值为整数1,否则为0,如下面的例子:cpp view plaincopyprint?1. #include2. #include3. 4. #defineVALUE55. 6. intmain(void)7. 8. char*ptr=NULL;9. intnum,count;10. 11. ptr=malloc(20);12. num=_builtin_constant_p(ptr)?20:20+10;13. printf(num=%dn,num);14. free(ptr);15. 16. count=_builtin_constant_p(VALUE)?20+VALUE:10;17. printf(count=%dn,count);18. 19. return0;20. 例子的输出结果:cpp view plaincopyprint?1. num=302. count=25 例子中的ptr为指针变量,所以_builtin_constant_p(ptr)的值为0,num的值为30。 (2)、函数_branch_check_的实现cpp view plaincopyprint?1. /*linux-/include/linux/compiler.h*/2. #define_branch_check_(x,expect)(3. int_r;4. staticstructftrace_branch_data5. _attribute_(_aligned_(4)6. _attribute_(section(_ftrace_annotate
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年托育机构意外伤害防控与监控系统全覆盖管理规范
- 内蒙古包头市2025-2026学年初三下学期第二次学情调研生物试题试卷含解析
- 广东省深圳市深圳龙岗区龙岭初级中学2026年初三4月考生物试题文试题含解析
- 2026年数字孪生工厂跨厂协同与知识迁移
- 2026年新疆莎车县下学期初三生物试题第二次月考考试试卷含解析
- 山东滨州阳信县市级名校2026年初三下学期第一次摸底考试化学试题文试卷含解析
- 2026年新疆十五五第一批技术创新项目指导计划申报指南
- 2026年农村区域性养老服务中心建设:每镇床位由40张增至80张经验
- 2026年养老社区智能家居适老化改造实施指南
- 2026年超滤反渗透双膜法工艺预处理与膜污染控制
- 三国演义三英战吕布课件
- 2026年苏州市职业大学单招职业技能测试模拟测试卷附答案
- 桥梁检测评定与加固技术课件 第2章 桥梁结构病害分析
- 2025-2026学年冀教版七年级英语上册(全册)知识点梳理归纳
- GB/T 42706.4-2025电子元器件半导体器件长期贮存第4部分:贮存
- 雨课堂在线学堂《信息素养-学术研究的必修课》作业单元考核答案
- 2025内蒙古单招计算机试题及答案
- 消防自动报警系统培训
- 消防思想政治教育
- 灭火系统运行管理规定细则
- 加油站防雷安全生产责任制度
评论
0/150
提交评论