You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32G473上cosf(x)比arm_cos_f32(x)快近6倍?测试存疑

问题分析与解答

核心结论

你的测试结果主要是DEBUG编译模式导致的,而非math.h的cosf天生比ARM Math函数快5-6倍。

具体原因

  1. 编译优化级别的影响
    DEBUG模式(通常对应-O0优化)会关闭几乎所有编译器优化,同时保留大量调试信息:
  • 标准库的cosf在ARM GCC环境下,默认会直接生成FPU硬件指令(比如VCOS.F32),无需函数调用开销,执行速度极快;
  • 而ARM Math库的arm_cos_f32/arm_cos_q15在DEBUG模式下,会保留完整的函数调用流程、未展开的内部循环、调试用的变量检查等,这些额外开销会让执行速度大幅下降。
  1. 实现机制的差异(DEBUG下被放大)
  • cosf依赖硬件FPU的原生余弦指令,是硬件级的单周期(或少数周期)计算;
  • ARM Math的余弦函数是软件实现(查表+插值算法),在无优化的DEBUG模式下,函数调用、循环展开、内存访问的开销被无限放大,导致速度远慢于硬件指令。
  1. 测试代码的优化漏洞
    你的测试用例中输入值是固定的0.0F,在RELEASE模式下编译器会直接将整个循环优化为value = 1.0F,完全跳过循环执行。这种测试结果没有参考意义,需要修改测试逻辑避免被优化。

正确的测试建议

  1. 切换到RELEASE模式测试
    开启-O2或-O3优化(这是嵌入式产品实际运行的模式),此时ARM Math函数会被编译器优化,函数调用开销降低、内部循环展开,性能会大幅提升,甚至在部分场景下和cosf持平或更优。

  2. 修改测试代码避免编译优化
    使用volatile修饰变量,或者让输入值随循环动态变化,确保编译器无法提前计算结果:

#define REPS 1000000
uint32_t rep = REPS;
uint32_t start = HAL_GetTick();
volatile float value;
volatile float input = 0.0F;

while(rep--) {
    value = cosf(input);
    input += 0.00001F;
    // 防止input溢出
    if(input > 2*M_PI) input -= 2*M_PI;
}
uint32_t end = HAL_GetTick();
duration[0] = end - start;

// ARM Math函数测试同理修改输入值
rep = REPS;
start = HAL_GetTick();
input = 0.0F;
while(rep--) {
    value = arm_cos_f32(input);
    input += 0.00001F;
    if(input > 2*M_PI) input -= 2*M_PI;
}
end = HAL_GetTick();
duration[1] = end - start;

内容的提问来源于stack exchange,提问作者Chris_B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 21:40:02