news 2026/4/18 2:08:32

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
<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

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

基于multisim的光控灯电路设计

(1)当光照强度在 0lx-300lx之间时,照明系统自动开启,喇叭不发报警声; (2)当光照强度在300lx-10000lx之间时,照明系统自动熄灭,喇叭不发出报警声; (3)当光照强度大于10000lx时,喇叭发出报警声。 仿真图: 仿…

作者头像 李华
网站建设 2026/4/16 15:58:44

Linux-sh -c \dirname

1. 核心深度解析:sh -c (子 Shell 运行) sh -c 的作用是启动一个临时的 子 Shell 来执行引号内的复杂命令字符串。为什么要用它?支持复合指令:xargs 默认只能接一个命令。如果你想用 &&、; 或者 |(管道)组合多…

作者头像 李华
网站建设 2026/4/15 16:31:15

“英”领物联:英飞凌详解构成物联网的五大元素

lin收发器 想必大家对于半导体的概念都不陌生了,那么对于拥有完备功能的物联网设备而言,都需要搭载哪些不可或缺的半导体器件,您是否也了如指掌呢?英飞凌提出了五大硬件元素的概念,分别指的是感知、计算、执行、连接和…

作者头像 李华
网站建设 2026/4/16 19:01:50

学生数据统计不再头疼,学工一体化平台助力辅导员高效减负

✅作者简介:合肥自友科技 📌核心产品:智慧校园平台(包括教工管理、学工管理、教务管理、考务管理、后勤管理、德育管理、资产管理、公寓管理、实习管理、就业管理、离校管理、科研平台、档案管理、学生平台等26个子平台) 。公司所有人员均有多…

作者头像 李华
网站建设 2026/4/10 18:14:21

<span class=“js_title_inner“>全栈“进化”公开课邀您参加|文心Moment大会走进大模型高效微调与极致推理全栈工程实践</span>

大模型效果越来越强,为什么真正上线却越来越难?从训练到推理、从算力到部署,工程能力正在成为决定成败的关键。从“模型可用”到“工程好用”,大模型正在经历一场真正的全栈进化。 1月22日下午13:00,全栈“…

作者头像 李华