Android 本地代码中的LIKELY和UNLIKELY宏

Qt中的主要宏定义 Qt 中的宏定义主要用于‌启用元对象系统(信号槽、反射)、实现跨平台兼容、封装私有实现细节(Pimpl 模式)及控制编译行为‌,是 Qt 框架区别于标准 C++ 的核心机制 。‌‌ 按作用分类:元对象系统(Meta-Object System)、信号与槽(Signals & Slots)、版本与条件编译 、平台与编译器检测、动态库导出/导入、C++ 特性与编译器兼容宏、调试与断言、国际化、工具与兼容宏 阅读详情

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

  

 

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

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

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

 

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

和

执行的结果是一样的。

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

也可以这样写:

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

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

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

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

 

10、驱动性能分析与优化-- 驱动热路径识别 热路径优化不是玄学。用perp定位热点,用调用链分析找到根因,用内联和分支预测优化代码。每一步都要有数据支撑,不要靠猜。 阅读详情

相关推荐

ART对象内存分配过程解析(下)——内存分配阶段(Android 8.1)

经过内存分配过程的准备阶段,我们分析到了Heap的AllocObjectWithAllocator()方法。 接下来我们将具体分析对象内存分配的过程。 ART对象分配过程解析——内存分配阶段 AllocObjectWithAllocator方法 首先我们来看Heap的AllocObjectWithAllocator()方法(位置:/art/runtime/gc/heap-inl.h): templ......

卜大爷的博客 2万+

Android native开发:systeom/core/libcutils

封装了user id, app id, uid, cache_gid, ext gid, ext cache gid, shared gid, share app gid获取和转换函数。定义了很多AID_xxx的宏,build/tools/fs_config用来生成Android文件的。获取init管理的文件,path是init.rc中的文件路径,返回fd。对__builtin_popcount的封装,计算二进制中1的个数。atomic相关的一些函数,遗留代码,不推荐使用。自定义list及相关操作函数。

yinminsumeng的博客 2139

C# 原生数字孪生的尝试

本文介绍了使用C#实现数字孪生的基本思路。首先从爱普生官网下载机器人3D模型,然后通过Blender创建并导出带动画的FBX模型。在WPF项目中,使用HelixToolkit.SharpDX等插件加载模型,通过Viewport3DX进行3D渲染。关键点是通过动画控制器接收真实设备信号来驱动模型动画,实现物理实体与虚拟模型的同步。文中提供了完整的代码实现,包括模型导入、动画播放控制等核心功能。该方法为构建数字孪生系统提供了一种可行的技术方案。

qq_33529095的博客 1331

linux中 likely与unlikely

照抄别人的日志.. 看内核时总遇到if(likely( )){}或是if(unlikely( ))这样的语句,最初不解其意,现在有所了解,所以也想介绍一下。likely() 与 unlikely()是内核(我看的是2.6.22.6版本,2.6的版本应该都有)中定义的两个宏。位于/include/linux/compiler.h中,具体定义如下:#define likely(x) __bui

1736

【异常】Codybuddy Error Code: 14003 too many requests 限流报错问题排查与解决指南

14003报错本质为服务端限流拦截,并非账号封禁或程序致命故障,90%以上的场景可通过等待冷却+规范使用行为解决。通过本文的排查步骤,可快速恢复工具使用,同时规避后续重复触发该问题。

奶爸的编程之路,也就一周冷个三天 1253

运放单电源供电和双电源供电的实际应用案例

文章摘要:本文对比分析了运放单电源与双电源供电的典型应用场景及电路设计要点。单电源供电适用于低成本、小体积设备,如便携音箱(5V供电+中点偏置)、工业4-20mA信号转换(12V供电+电压跟随)和物联网传感器(3.3V低功耗设计);双电源供电则适合高精度要求场景,如Hi-Fi音响(±15V对称输出)、医疗设备(±5V微弱信号放大)和精密仪器(±15V宽动态范围)。文末提供常见运放选型对照表,涵盖LM324、TL082等型号的供电参数与核心特性,为不同应用场景提供选型参考。(149字)

qq_37999850的博客 608

likely和unlikely宏

首先,无论在何处,当我们遇到宏likely和宏unlikely时,都要明确一点:   if(likely(value)) 等价于 if(value)   if(unlikely(value)) 也等价于 if(value)     也就是说 ,当value值为真时执行if分支,为假时执行else分支,从阅读和理解代码的角度来看,是一样的!!!     以下为这两个宏的一般定义: #def

jianghaiyoushan的专栏 517

19、利用PostGIS进行空间分析:更高效的矢量分析方法

本文介绍了如何利用PostGIS进行高效灵活的矢量空间分析,重点探讨了在选址安静住宅场景中使用缓冲区和距离测量两种方法的实现与优化。通过QGIS与PostGIS结合,演示了数据上传、CTE应用、ST_Intersects与ST_Distance函数对比,并深入分析了横向子查询在提升查询性能和代码可读性方面的优势。文章还比较了不同方法的适用场景,并以房地产开发选址为例展示了完整分析流程,最后总结了PostGIS在空间分析中的强大能力与未来应用前景。

d3e4f的博客 92

likely与unlikely

likely与unlikely互换或不用都不会影响程序的正确性,只是可能会影响程序的效率。 if(likely(x))  //认为x通常为1 if(unlikely(x)) //认为x通常为0      

Joe的专栏 4733

YOLO26 标签分配机制:STAL 小目标感知分配策略

YOLO26提出的STAL标签分配策略通过尺度感知机制优化了小目标检测性能。该方法根据目标面积将检测对象分为小、中、大三类,分别采用差异化的分配参数(TopK数量、IoU阈值和中心度权重),特别是对小目标采用更宽松的匹配条件和更高的中心度权重。实验结果表明,STAL策略显著提升了小目标检测精度(AP_small),同时保持了整体检测性能(mAP),为解决目标检测中尺度不平衡问题提供了有效方案。

一键难忘的博客 789

FPGA和USB3.0通信-USB3.0 PHY介绍

可以和FPGA搭配使用的USB3.0 PHY芯片通过之前的介绍<FPGA和USB3.0通信-USB3.0协议介绍USB3.0 PHY简介首先我们需要了解PHY具体完成哪些工作以及我利...

OpenFPGA的博客 4940

likely()与unlikely()函数的意义

看内核时总遇到if(likely( )){}或是if(unlikely( ))这样的语句,最初不解其意,现在有所了解,所以也想介绍一下。 likely() 与 unlikely()是内核(我看的是2.6.22.6版本,2.6的版本应该都有)中定义的两个宏。位于/include/linux/compiler.h中, 具体定义如下: #define likely(x) __builtin_e

jsn_ze的专栏 917

Windows11上pip安装IsaacSim5.1.0与IsaacLab

本文详细介绍了CUDA Toolkit 12.8.0、IsaacSim和IsaacLab的安装过程。首先从NVIDIA官网下载并安装CUDA Toolkit 12.8.0,然后通过miniforge创建conda环境(env_isaacsim)安装IsaacSim相关Python包,解决了Windows长路径问题。成功运行IsaacSim后,克隆IsaacLab仓库并完成安装验证,最后通过创建空场景测试环境配置。整个安装过程包含详细的命令行操作和问题解决方法,为机器人仿真开发环境搭建提供了完整指导。

拥抱具身智能,昇腾Ascend C 378

Android系统Surface机制的SurfaceFlinger服务的线程模型分析

在前面两篇文章中,我们分析了SurfaceFlinger服务的启动过程以及SurfaceFlinger服务初始化硬件帧缓冲区的过程。从这两个过程可以知道,SurfaceFlinger服务在启动的过程中,一共涉及到了三种类型的线程,它们分别是Binder线程、UI渲染线程和控制台事件监控线程。在本文中,我们就将详细分SurfaceFlinger服务的线程模型,即上述三种类型的线程是如何运行和交互的。

老罗的Android之旅 4万+

YOLOv11 TensorRT极致加速:C++部署性能优化完全指南

购买即可解锁300+YOLO优化文章,并且还有海量深度学习复现项目,价格仅需两杯奶茶的钱,别人有的本专栏也有!

LXY_LOVE36的博客 118

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

android多个usb摄像头,Android中多USB摄像头解决方案——UVCCamera源码分析(三)

前面几章我们分析了UVCCamera的初始化、预览相关的准备工作,本章我们则来看看startPreview的整个流程。按照惯例我们先大概看下调用的时序图:startPreview接着之前开启预览过程最终走到AbstractUVCCameraHandler.CameraThread的handleStartPreview方法,继而调用UVCCamera的startPreview,如上图所示,UVCCa...

weixin_32046225的博客 1344

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

android读取多个usb摄像头,Android中多USB摄像头解决方案——UVCCamera源码分析(三)...

前面几章我们分析了UVCCamera的初始化、预览相关的准备工作,本章我们则来看看startPreview的整个流程。按照惯例我们先大概看下调用的时序图:startPreview接着之前开启预览过程最终走到AbstractUVCCameraHandler.CameraThread的handleStartPreview方法,继而调用UVCCamera的startPreview,如上图所示,UVCCa...

weixin_39639550的博客 962

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

上一篇: Android SurfaceFlinger中的工作线程:threadLoop()
下一篇: Android SurfaceFlinger中的Layer,LayerDim,LayerBlur,LayerBuffer
DroidPhone
博客等级 码龄16年 3750粉丝 51原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值