XTOOL朗仁新能源维修设备打造一站式解决方案
2026/6/3 16:44:14
FMA(Fused Multiply-Add,融合乘加)是一种在现代处理器(如 Intel Haswell 及以后、AMD Zen 架构、ARM Cortex-A 系列等)中广泛支持的浮点运算指令。它的基本形式为:
FMA ( a , b , c ) = a × b + c \text{FMA}(a, b, c) = a \times b + cFMA(a,b,c)=a×b+c
但关键区别在于:FMA 指令在硬件上将乘法和加法融合为一个操作,只进行一次舍入(而不是先乘后加各舍入一次)。
doubleresult=a*b+c;a * b,得到一个中间结果(需舍入到目标浮点格式,如 double)c相加,再次舍入// 编译器自动优化,或显式使用 std::fma(a, b, c)doubleresult=std::fma(a,b,c);a * b + c在内部以**更高精度(如双倍精度)**完成运算✅精度更高:避免了中间舍入误差,尤其在:
a * b与c量级接近但符号相反(避免灾难性抵消后的误差放大)示例:若
a = 1e10,b = 1e-10,c = -1.0,理论上a*b + c = 0
传统方式可能因a*b舍入为1.0000000000000002,导致结果为2e-16;
FMA 可更接近 0(误差更小)。
MUL + ADD,减少指令数_mm256_fmadd_pd)✅ 典型加速场景:
a*b + c替换为 FMA,除非启用-ffast-math(GCC/Clang)或/fp:fast(MSVC)std::fmac远大于a*b),FMA 的单次舍入可能不如两次舍入“幸运”(但统计上 FMA 更优)#include<cmath>doubler=std::fma(a,b,c);// 显式调用# 启用 FMA 指令(需目标 CPU 支持)- mfma# x86- mfp16# ARM(部分)# 或启用 fast-math(自动融合)- ffast-math - fma# Clang 特定#include<immintrin.h>__m256d r=_mm256_fmadd_pd(a_vec,b_vec,c_vec);| 维度 | 传统 MUL+ADD | FMA |
|---|---|---|
| 舍入次数 | 2 次 | 1 次(精度更高) |
| 指令数 | ≥2 | 1 |
| 吞吐量 | 较低 | 高(尤其向量化时) |
| 适用场景 | 通用 | HPC、AI、数值敏感计算 |
| 控制方式 | 默认行为 | 需显式调用或编译器优化 |
✅建议:在高性能数值计算中,主动利用 FMA(通过
std::fma或编译器优化),但需验证数值稳定性;在要求严格可重现性时,注意跨平台一致性。