Published on

FMA 指令

硬件 FMA(Fused Multiply-Add)指令是现代 CPU 和 GPU 中的一种基础算术指令,它能在单个时钟周期内完成 乘法和加法的融合运算,即计算 a * b + c。以下是关于硬件 FMA 指令的详细解析:


1. FMA 的数学表达式

FMA 执行的操作:

FMA(a,b,c)=a×b+c\text{FMA}(a, b, c) = a \times b + c
  • 输入:三个操作数(a, b, c
  • 输出a * b + c 的精确结果

2. 硬件 FMA 的核心特性

(1)融合计算(Fused)

  • 传统方式:先计算 a * b(舍入一次),再与 c 相加(再舍入一次),共 两次舍入误差
  • FMA 方式:乘法和加法在硬件层面合并为 单一操作,仅 一次舍入误差,显著提高数值精度。

(2)高性能

  • 相比分开的乘法和加法指令,FMA 的吞吐量通常 提高 2 倍(1 条指令 vs 2 条指令)。
  • 在 NVIDIA GPU 中,FMA 是 Tensor Core 的核心操作之一,支持混合精度计算(如 FP16 输入 + FP32 累加)。

(3)低延迟

  • 现代 CPU/GPU 的 FMA 单元经过高度优化,延迟通常低于分开的乘法和加法。

3. 硬件支持

CPU 支持

  • x86:Intel Haswell(2013)及以后的 CPU 支持 FMA3 指令集(如 vfmadd132ps)。
  • ARM:Neon 和 SVE 指令集支持 FMA(如 vfma.f32)。

GPU 支持

  • NVIDIA:从 Kepler 架构(2012)开始支持 FMA,Volta/Turing/Ampere 架构的 Tensor Core 进一步优化。
  • AMD:GCN 和 RDNA 架构均支持 FMA。

4. FMA 的硬件实现(以 GPU 为例)

在 NVIDIA GPU 中,FMA 指令的执行流程:

  1. 乘法阶段:计算 a * b(保留完整中间精度,不立即舍入)。
  2. 加法阶段:将中间结果与 c 相加。
  3. 最终舍入:对结果进行 一次舍入(IEEE 754 标准)。

5. 为什么 FMA 对深度学习至关重要?

  1. 矩阵乘法的核心:神经网络中的 Q*K^T、全连接层等本质是大规模乘加运算。
  2. 精度保障:减少舍入误差对训练/推理的影响(尤其是梯度计算)。
  3. 性能瓶颈突破:FMA 是 GPU 算力(TFLOPS)的主要贡献者。

例如,NVIDIA A100 的 FP16 FMA 吞吐量高达 312 TFLOPS,远超传统指令。


6. 代码中的 FMA 优化

在您之前的 CUDA 代码中:

qk_vec = vllm::fma(q[ii], k[ii], qk_vec);

编译器会将其编译为硬件 FMA 指令(如 PTX 指令 fma.rn.f32),而非分开的 mul + add,从而最大化性能。


7. 验证 FMA 指令生成

可通过检查 PTX 汇编确认:

nvcc --ptx -O3 your_code.cu

输出中会看到类似指令:

fma.rn.f32 d, a, b, c;  // 标准的FMA指令

总结

硬件 FMA 指令是高性能计算的基石,通过 融合运算减少舍入误差提升吞吐量,为深度学习、科学计算等场景提供了关键加速。

THE END