当前位置: 首页 > news >正文

<span class=“js_title_inner“>同事用“与运算“改了这几行代码,运行效率直接起飞~</span>


正文


大家好,我是bug菌~

1

问题背景

最近由于项目指标的需求,查了下程序各个部分的运行效率,发现一直用的环形缓冲区在耗时占比中还挺突出,于是过了一遍代码并尝试着去优化一下,没想到改动不大却得到了较大的效率提升。

如下是之前环形缓冲区的一些代码片段:

#define BUFFER_SIZE 512 uint16_t buffer[BUFFER_SIZE]; uint16_t index = 0; ...... index = (index + 1) % BUFFER_SIZE; ......

当程序高频率的调用含有取模的运算接口时执行时间超出了设计预期,同时在低优化等级(毕竟如果编译器进行了各种优化,那就不好聊下去了)下对取模运算进行了相关sysclock的测量,确实也是效率不高,于是我打算用更高效的运算方式把它替换掉。

2

与运算代替取模

当然了,与运算至少全面替代取模运算没那么容易,毕竟如果能够完全替代,也不会有人用取模了,当时对于嵌入式行业我觉得最有意思的是它并不需要非常的通用,嵌入式只需要在特定的领域,特定的工况下能做到极致就可以了,有取舍才能在有限的资源下把平台充分利用起来。

同样的思路取模运算确实很强大,但是我并不需要利用它所覆盖的方方面面,所以当除数是2的幂(即n = 2^k)时,与运算同样可以满足我的需求:

// 当 n 是 2 的幂(n = 2^k)时 a % n = a & (n - 1) // 等价的情况(n是2的幂) a % 8 == a & 7 // 8 = 2^3 a % 16 == a & 15 // 16 = 2^4 a % 32 == a & 31 // 32 = 2^5

我们知道% 运算通常需要除法指令,开销较大,而& 运算只需要按位与,速度快很多。

所以对应环形缓存区只需要优化下:

#define BUFFER_SIZE 512 // 必须为2的幂 #define BUFFER_MASK (BUFFER_SIZE - 1) // 511 = 0x1FF uint16_t buffer[BUFFER_SIZE]; uint16_t index = 0; ...... index = (index + 1) & BUFFER_MASK; // 快速回绕 ......

3

再细致一点

聊到这里,来龙去脉应该讲清楚了,其实不管了是在这一次的环形缓存区的优化中有所感悟这种方法,只要是在当除数是2的幂时这种方式都能大大提高效率,特别是一些实时性应用场景,一通百通。

比如说你要进行ADC窗口滑动:

samples[sample_index] = adc_read(); ...... // sample_index = (sample_index + 1) % WINDOW_SIZE; //直接方式 sample_index = (sample_index + 1) & WINDOW_MASK; ......

一些限制和风险我们也要非常有数,一些bug大部分都是因为我们没有提前想到:

1、在性能关键路径且除数是2的幂时,才考虑使用与运算替代取模运算,其他地方其实无关痛痒也没必要替换,所以可以做一些防御性检测:

#ifndef IS_POWER_OF_TWO #define IS_POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0) #endif #define QUEUE_SIZE 128 #if !IS_POWER_OF_TWO(QUEUE_SIZE) #error "QUEUE_SIZE must be power of two for optimization" #endif #define QUEUE_MASK (QUEUE_SIZE - 1)

2、如果是处理负数大概率会出问题,要留意。

最后

好了,今天就跟大家分享这么多了,如果你觉得有所收获,一定记得点个~

唯一、永久、免费嵌入式技术知识分享平台

推荐专辑 点击蓝色字体即可跳转

MCU进阶专辑

嵌入式C语言进阶专辑

“bug说”专辑

专辑|Linux应用程序编程大全

专辑|学点网络知识

专辑|手撕C语言

专辑|手撕C++语言

专辑|经验分享

专辑|电能控制技术

专辑 | 从单片机到Linux

http://www.jsqmd.com/news/333301/

相关文章:

  • 【无人机控制】多旋翼无人机横向动力学的鲁棒控制附matlab代码
  • 手性分离色谱柱推荐品牌哪家企业质量好?性能参数详解 - 品牌推荐大师1
  • 导师严选9个降AI率网站,解决论文AI痕迹难题,千笔·降AIGC助手助你轻松过关
  • 从此告别拖延,AI论文写作软件千笔·专业论文写作工具 VS 万方智搜AI
  • 详解Splay平衡树 - 实践
  • 2026年首月福建营销策划公司核心能力实测:全域整合与区域深耕效果的综合绩效推荐 - 品牌推荐
  • 技术分化与效果量化双轮驱动 | 2026浙江营销策划公司TOP5实证研究榜单推荐 - 品牌推荐
  • 椭圆形光斑手机补光灯设计报告
  • 2026年铁路地铁电力电缆生产厂家推荐:中低压、低压、中压、变频等电缆生产厂家推荐 - 品牌2025
  • 京东卡(E卡)回收高效平台有哪些,经典三家推荐 - 淘淘收小程序
  • 2026年福建营销策划公司权威测评报告:基于百家客户匿名反馈的口碑深度解析 - 品牌推荐
  • 2026年中国电缆一线品牌推荐:阻燃防火电缆国内一线品牌推荐排名名单 - 品牌2025
  • <span class=“js_title_inner“>MySQL 反模式:为什么资深 DBA 看到 ENUM 类型直摇头?</span>
  • 2026年浙江营销策划公司权威测评报告:基于百家客户匿名反馈的口碑深度解析 - 品牌推荐
  • 2026年江西营销策划公司推荐:基于制造业与电商场景评价,解决获客与转化核心痛点 - 品牌推荐
  • 2026最新防火涂料行业深度测评:钢结构 / 隧道 / 电缆 / 饰面型涂料适配指南 - 深度智识库
  • 2026最新停车场设备推荐!国内优质智能/机械式停车场设备权威榜单发布,资质服务双优破解停车难题 - 品牌推荐2026
  • [PYTHON] import foo.bar 和 from foo import bar 有何不同
  • 尖塔游记
  • 2026年2月四川工程机械出租行业云梯车、高空车、 云梯车租赁、 高空车租赁、 云梯车出租竞争格局深度分析报告 - 2026年企业推荐榜
  • 2026年首月浙江营销策划公司核心能力实测:全域整合与智能增长效果的综合绩效推荐 - 品牌推荐
  • 成都消防服务优选:四川中安锦胜——专业可靠的消防检测维保伙伴 - 深度智识库
  • 2026低压电力电缆优选:ZC-YJV源头厂家信赖之选,WDZN-YJY低烟无卤电力电缆,低压电力电缆企业推荐 - 品牌推荐师
  • 电商带货三步式快速开播工具:全能播Live Omni 解锁 AI 直播降本增效新路径
  • 2026年2月成都乳胶漆/涂料 /环保涂料/真石漆/仿石漆厂家竞争格局深度分析报告 - 2026年企业推荐榜
  • 闲置京东e卡别浪费!正规回收全流程拆解,新手也能轻松上手 - 可可收
  • 2026年电缆生产厂家名单:电缆生产厂家排名,知名的电缆生产厂家推荐精选 - 品牌2025
  • 2026年江西营销策划公司推荐:企业增长痛点深度评测,覆盖多场景服务排名 - 品牌推荐
  • 2026年全国API冻干粉哪家强?多家厂家解析 覆盖多领域原料供应 - 深度智识库
  • 【TVM教程】设备/目标交互