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

Clang编译AVX浮点SIMD代码时为何额外插入FMA指令?

额外FMA指令的作用

vrcpps是x86提供的快速单精度倒数近似指令,硬件直接给出的近似倒数只有约1112位有效精度,远达不到单精度浮点数23位尾数的精度要求。Clang生成的两条FMA指令是执行**1次牛顿-拉夫逊迭代修正**,把倒数近似值的精度提升到接近原生浮点除法的水平,误差控制在12个ulp以内,满足-Ofast模式下的精度要求。

把指令逻辑按计算流程拆解开就很清楚:

  • 计算到vrcpps ymm2, ymm0时,ymm2存的是分母x = num+1400的粗略倒数r0 ≈ 1/x
  • 接下来vmulps ymm3, ymm1, ymm2算出的是粗略商值q0 = 278*num * r0 ≈ 278*num/x
  • 第一条FMA vfmsub213ps ymm0, ymm3, ymm1计算商值的误差项:err = q0 * x - 278*num。如果q0是完全精确的,err应该为0,err的大小直接反映q0和精确值的偏差
  • 第二条FMA vfnmadd213ps ymm0, ymm2, ymm3执行迭代修正:q = q0 - r0 * err,修正后的q就是精度达标的最终结果。

这种实现是-Ofast开启-freciprocal-math优化后的默认选择:允许用倒数近似+少量迭代替换原生除法,在精度损失极小的前提下换更高性能。

与vdivps实现的性能对比

性能对比基于Skylake微架构的公开实测指令参数:

  • 普通向量算术指令(vaddps/vmulps/FMA类指令):单条延迟4周期,每周期可发射2条,跑在CPU的通用向量执行端口
  • vrcpps(YMM):延迟4周期,每周期可发射1条
  • vdivps(YMM单精度除法):延迟11周期,每11周期才能发射1条,跑在独立的慢速除法执行单元,和普通向量指令不共享执行资源

两种实现的实际表现差异:

  • 单次调用端到端延迟:原生vdivps版本总延迟约15周期(4周期算分母+11周期除法),rcp+迭代版本总延迟约20周期,单次顺序执行时vdivps延迟略低。
  • 稳态吞吐量(批量计算场景):rcp+迭代版本的所有指令都使用高带宽的通用向量执行单元,指令间可充分重叠执行,稳态下每67周期就能完成一组8个float的计算;而`vdivps`受限于除法单元的低吞吐量,每11周期才能完成一组计算,批量处理时rcp+迭代版本性能是`vdivps`版本的1.52倍。
  • 精度层面,经过1次牛顿迭代修正的rcp计算结果和vdivps的结果偏差通常在1~2个ulp,绝大多数工程场景下完全可用。

补充说明:-O3模式默认不开启快速浮点优化,必须严格遵循IEEE 754浮点规范,因此会直接使用vdivps指令,不会采用rcp近似方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 02:06:32