`

Android 本地代码中的LIKELY和UNLIKELY宏

 
阅读更多

阅读Android Frameworks中的C++代码时,经常会碰到在条件判断语句中使用了LIKELY和UNLIKELY这两个宏,找到这两个宏的定义如下:

view plain
  1. #defineLIKELY(exp)(__builtin_expect((exp)!=0,true))
  2. #defineUNLIKELY(exp)(__builtin_expect((exp)!=0,false))

long __builtin_expect (long exp, long c)是GCC的内建函数,解析如下:

你可以使用__builtin_expect给编译器提供分支预测的信息,通常,你因该明确使用这个编译选项(‘-fprofile-arcs’),因为很多程序员在如何预测他们编写的代码实际如何执行方面都很糟糕,使用这个宏可以很方面地让编译器优化分支跳转的代码。

这个函数的返回值就是exp:一个整形表达式,c必须是一个常量,该内建函数从语义上是表明:我们期望exp == c。

所以,如果你不考虑程序执行的效率,加不加LIKELY和UNLIKELY宏,执行的结果是一样的:

view plain
  1. if(LIKELY(exp))
  2. {
  3. }
  4. else
  5. {
  6. }

view plain
  1. if(exp)
  2. {
  3. }
  4. else
  5. {
  6. }

执行的结果是一样的。

那为什么还要使用这两个宏定义? 以汽车的速度为例子,如果速度超过200公里/小时表示有异常发生,代码可以这样写:

view plain
  1. if(speed>=200){
  2. //异常处理代码
  3. .....
  4. stop();
  5. }else{
  6. //正常处理代码
  7. continue();
  8. }

也可以这样写:

view plain
  1. if(speed<200){
  2. //正常处理代码
  3. continue();
  4. }else{
  5. //异常处理代码
  6. .....
  7. stop();
  8. }

这两个方案执行后都是正确的,但是显然效率是不一样的,因为大多数情况下,汽车的速度不会超过200公里/小时,当采用第一个方案时,大多数情况下,代码执行到这里时CPU都要执行分支跳转的操作,这破坏了CPU的指令执行流水线,对性能的影响是显而易见的。而第二个方案则避免了这一问题,因为大多数时候都是顺序执行的。

对于第一种方案,我们可以加上UNLIKELY宏来让编译器来优化:

view plain
  1. if(UNLIKELY(speed>=200)){
  2. //异常处理代码
  3. .....
  4. stop();
  5. }else{
  6. //正常处理代码
  7. continue();
  8. }

加上UNLIKELY宏后,相当于告诉编译器:速度大于200是很少出现的。这样编译器在编译代码时,会适当地调整条件判断的方式,让CPU的指令执行顺序尽可能不被打乱,已达到优化性能的效果。

所以,对于第二种方案,我们同样可以加上LIKELY宏:

view plain
  1. if(LIKELY(speed<200)){
  2. //正常处理代码
  3. continue();
  4. }else{
  5. //异常处理代码
  6. .....
  7. stop();
  8. }


阅读Android Frameworks中的C++代码时,经常会碰到在条件判断语句中使用了LIKELY和UNLIKELY这两个宏,找到这两个宏的定义如下:

view plain
  1. #defineLIKELY(exp)(__builtin_expect((exp)!=0,true))
  2. #defineUNLIKELY(exp)(__builtin_expect((exp)!=0,false))

long __builtin_expect (long exp, long c)是GCC的内建函数,解析如下:

你可以使用__builtin_expect给编译器提供分支预测的信息,通常,你因该明确使用这个编译选项(‘-fprofile-arcs’),因为很多程序员在如何预测他们编写的代码实际如何执行方面都很糟糕,使用这个宏可以很方面地让编译器优化分支跳转的代码。

这个函数的返回值就是exp:一个整形表达式,c必须是一个常量,该内建函数从语义上是表明:我们期望exp == c。

所以,如果你不考虑程序执行的效率,加不加LIKELY和UNLIKELY宏,执行的结果是一样的:

view plain
  1. if(LIKELY(exp))
  2. {
  3. }
  4. else
  5. {
  6. }

view plain
  1. if(exp)
  2. {
  3. }
  4. else
  5. {
  6. }

执行的结果是一样的。

那为什么还要使用这两个宏定义? 以汽车的速度为例子,如果速度超过200公里/小时表示有异常发生,代码可以这样写:

view plain
  1. if(speed>=200){
  2. //异常处理代码
  3. .....
  4. stop();
  5. }else{
  6. //正常处理代码
  7. continue();
  8. }

也可以这样写:

view plain
  1. if(speed<200){
  2. //正常处理代码
  3. continue();
  4. }else{
  5. //异常处理代码
  6. .....
  7. stop();
  8. }

这两个方案执行后都是正确的,但是显然效率是不一样的,因为大多数情况下,汽车的速度不会超过200公里/小时,当采用第一个方案时,大多数情况下,代码执行到这里时CPU都要执行分支跳转的操作,这破坏了CPU的指令执行流水线,对性能的影响是显而易见的。而第二个方案则避免了这一问题,因为大多数时候都是顺序执行的。

对于第一种方案,我们可以加上UNLIKELY宏来让编译器来优化:

view plain
  1. if(UNLIKELY(speed>=200)){
  2. //异常处理代码
  3. .....
  4. stop();
  5. }else{
  6. //正常处理代码
  7. continue();
  8. }

加上UNLIKELY宏后,相当于告诉编译器:速度大于200是很少出现的。这样编译器在编译代码时,会适当地调整条件判断的方式,让CPU的指令执行顺序尽可能不被打乱,已达到优化性能的效果。

所以,对于第二种方案,我们同样可以加上LIKELY宏:

view plain
  1. if(LIKELY(speed<200)){
  2. //正常处理代码
  3. continue();
  4. }else{
  5. //异常处理代码
  6. .....
  7. stop();
  8. }

分享到:
评论

相关推荐

    linux内核中的likely和unlikely.pdf

    linux内核中的likely和unlikely.pdf

    FAQ gnu C likely unlikely

    FAQ gnu C likely unlikely statement explain. Compiler optize C language code.

    Android代码-Android壁纸应用程序

    Zero is an open source, ad-free live wallpaper app for android. Zero is available on the Google Play. The project is very young and most likely very buggy; right now the application is still in ...

    Android代码-android

    You will likely also need Eclipse for Android development from http://www.eclipse.org The default project contained in the project is just a sample. You can replace it with your own ...

    Android代码-android-screenshot-lib

    Android Screenshot library On-demand screenshots during Android integration tests This framework uses ddmlib to capture screenshots from your device, and addresses some issues around taking ...

    unlikely:gcc 分支预测宏

    不太可能 GCC 分支预测宏。 安装 使用安装: $ clib install clibs/file 应用程序接口 likely (expr) unlikely(expr)

    Android代码-Slide

    Slide is an open source, ad free Reddit browser for Android. It is based around the Java Reddit API Wrapper. Slide is available on the Google Play Store and F-Droid. There is an active ...

    Android代码-dante

    This is the very first release of Dante, the api will (most likely) change for the better with successive iterations. Installation Simply add the following to your build.gradle: repositories { ...

    Android代码-zippy-android-talk

    This is the code used during my talk at Google I/O 2010. Talk summary: http://code.google.com/events/io/2010/sessions/writing-zippy-android-apps.html ...likely (intentionally) wrong! :)

    Android代码-Ledman

    Runs on Rasbian Jissie and likely other things to. Install First install pi-blaster. Then get Ledman. These command assume you use Rasbian Jissie with the Systemd (which is default), but feel free to...

    Android代码-一个建立在RxJava架构Android实例项目

    Reference Architecture for Android using RxJava This is an ambitious reference project of what can be done with RxJava to create an app based on streams of data. In the repository you will find ...

    Android代码-LoveLive学园偶像祭多账户管理SIFAM

    Abandoned I am no longer working on SIFAM and have no plans to continue it. If someone wants to take over they can SIFAM ... (Most likely wont work in default SDK emulator) Dependancies A

    Android代码-java-dotenv

    Anything that is likely to change between deployment environments–such as resource handles for databases or credentials for external services–should be extracted from the code into environment ...

    Android Programming for Beginners.pdf

    More likely, the reason developing for Android gives such a buzz is the nature of the devices. They are deeply personal. You can create apps that actually interact with people's lives. You can educate...

    Data Structures & Algorithms Interview Questions You'll Most Likely Be epub

    Data Structures & Algorithms Interview Questions You'll Most Likely Be Asked 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 查看此书详细信息请在美国亚马逊官网搜索此书

    Wrox.Professional.Android.2.Application.Development.pdf

    A host of Android handsets are now available to tempt consumers, including phones with QVGA screens and powerful WVGA devices like the Motorola Droid and the Google Nexus One. The real win though, is ...

    社交分享按钮Likely.zip

    Likely 不寒碜的社交分享按钮。 标签:Likely

    ANDROID 蓝牙配对连接发数据

    这是本人在网上收集的代码,里面有4个源代码,仅供参考,

    Android Studio工程导入,仅需三步便可运行

    本学期刚刚学习Android开发,使用Android studio 中出现了许多的小问题,其中之一就是工程的导入问题,Android开发示例程序,好多打开之后会出现,程序乱码、需要下载很多缺失文件、路径不对文件打开失败、缺少R等等...

Global site tag (gtag.js) - Google Analytics