找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2654

积分

1

好友

369

主题
发表于 9 小时前 | 查看: 1| 回复: 0

最近在优化项目指标时,发现程序中一直使用的环形缓冲区在耗时占比中颇为突出。经过代码审查和尝试性优化,仅通过几处小改动就获得了显著的效率提升。

以下是优化前环形缓冲区的部分代码片段:

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

当程序高频调用包含取模运算的接口时,其执行时间超出了设计预期。在低优化等级下(避免编译器过度优化影响分析),对取模运算进行系统时钟测量也证实了其效率不高。因此,我考虑用更高效的运算方式将其替换。

当然,用与运算全面替代取模运算并不容易,否则取模运算也就没有存在的必要了。在嵌入式开发领域,一个有趣的思路是:我们并不总是需要追求通用性。嵌入式系统往往只需在特定领域、特定工况下做到极致。适当的取舍,才能在有限的资源下充分利用平台。

同理,取模运算功能强大,但我并不需要它覆盖的所有场景。当除数是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;  // 快速回绕
......

到这里,核心原理已经讲清楚了。不仅是在这次环形缓冲区优化中,只要除数是2的幂,这种方法都能大幅提升效率,尤其适用于一些实时性要求高的应用场景,可以举一反三。

例如,在进行ADC窗口滑动采样时:

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

当然,我们也要充分意识到这种优化方法的限制和潜在风险,很多bug都源于考虑不周:

  1. 只在性能关键路径且除数是2的幂时,才考虑使用与运算替代取模运算。 其他地方影响不大,无需替换。可以进行一些防御性检测,这在编写健壮的C/C++代码时是很好的习惯:

    #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. 如果操作数可能是负数,使用与运算大概率会出问题, 需要特别留意其符号处理。

这次优化实践再次证明,深入理解底层原理,结合具体场景进行优化,往往能用简单的改动收获可观的性能提升。如果你在云栈社区探索更多关于嵌入式性能调优的讨论,或许会有新的启发。

性能提升示意图




上一篇:程序员如何构建代码资产?打造第一份被动收入的实战思路
下一篇:Python量化计算可转债凸性因子:实战应用指南与代码模板解析
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-18 18:14 , Processed in 0.476734 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表