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

Apple libm的sin函数在小输入时为何执行冗余乘法后返回x?

Apple libm sin函数小输入场景的冗余浮点乘法解析

问题背景

当输入x足够小时,sin(x)的最接近浮点数就是x,但Apple libm的sin函数并未直接返回x,而是执行了一次无实际结果使用的浮点乘法,关键代码如下:

/*  Make t0 volatile to force compiler to fetch it at run-time
    rather than optimizing away the multiplication.
*/
static volatile const double t0 = 1/3.;

/*  Get t0 once.  If we wrote "t0*t0", the compiler would load it
    twice, since it is volatile.
*/
const double t1 = t0;

/*  Perform a multiplication and pass it into an assembly construct to
    prevent the compiler from knowing we do not use the result and
    optimizing away the multiplication.
*/
__asm__("" : : "X" (t1*t1));

// Return the floating-point number nearest sine(x), which is x.
return x;

设计意图

这段冗余代码的核心目的是保证函数执行时间的一致性,避免分支带来的性能抖动:

  • 作为基础数学库,libm的调用场景常包含对延迟敏感的应用(如实时系统、高频数值计算),这类场景要求函数执行时间尽可能稳定,不能因输入不同出现大幅波动。如果小输入场景直接返回x,其执行时间会远短于需要泰勒展开、查表等复杂计算的场景,这种时间差可能引发时序问题。
  • 执行一次浮点乘法的开销极低,能让小输入场景的执行时间和其他场景的基础计算开销对齐,抹平分支导致的时间差异。

同时,代码中的特殊处理是为了防止编译器优化掉这个“无用”操作:

  • static volatile const double t0确保t0会在运行时被加载,而非被编译器提前做常量折叠优化。
  • __asm__("" : : "X" (t1*t1))通过空汇编语句向编译器传递“该乘法结果被使用”的信号,阻止编译器将整个乘法操作删除。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 16:04:51