news 2026/6/2 17:06:41

同事用“与运算“改了这几行代码,运行效率直接起飞~

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
同事用“与运算“改了这几行代码,运行效率直接起飞~


正文


大家好,我是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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/31 11:48:28

为什么AI开发者必须规划职业转型?2026年生存法则

一、AI大模型崛起:软件测试领域的颠覆性变革 当前,AI大模型技术正重塑软件开发全流程,软件测试从业者首当其冲面临职业挑战。随着AI代码生成工具的普及,传统测试任务如重复性用例执行、缺陷检测等正被自动化取代。例如&#xff0…

作者头像 李华
网站建设 2026/5/26 22:49:44

2026年职业蓝图:从码农到CTO的加速计划

软件测试从业者的独特优势与CTO之路‌ 在数字化转型浪潮中,软件测试从业者常被视为技术生态的“守门人”,但2026年的科技革命(如AI与DevOps普及)正重塑职业格局。测试工程师凭借对质量、风险与系统的深刻理解,拥有晋升…

作者头像 李华
网站建设 2026/5/6 5:10:09

耐达讯自动化Profibus总线光纤中继器在连接测距仪中的应用

在工业自动化领域,实时、可靠的数据传输是确保生产效率和系统稳定性的核心要素。Profibus协议作为主流的工业通信标准,在各类自动化设备中广泛应用。然而,面对长距离传输、电磁干扰等复杂工况,传统电缆传输的局限性逐渐凸显。耐达…

作者头像 李华
网站建设 2026/5/21 0:25:59

数据堆成山?虎贲等考 AI 让论文实证分析一键 “变废为宝”

还在对着几百份问卷数据抓耳挠腮?还在为实验数据的统计方法选择纠结到失眠?还在因数据分析报告缺乏逻辑被导师反复打回?在实证研究为王的学术时代,数据本身没有价值,高效的分析与精准的解读才是论文的 “硬核加分项”。…

作者头像 李华
网站建设 2026/5/14 5:25:39

【大数据毕设全套源码+文档】基于django+数据爬取的民族服饰数据分析系统的设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华