浮点外积运算(Floating-point Outer Product)是线性代数中的基础操作,它将两个向量相乘生成一个矩阵。在ARMv9架构引入的SME(Scalable Matrix Extension)扩展中,FMOPA(Floating-point Multiply Outer Product Accumulate)和FMOPS(Floating-point Multiply Outer Product Subtract)指令专门用于高效实现这一运算。
这些指令的核心特点是:
所有FMOPx指令都遵循相似的编码结构,以半精度单向量模式为例:
code复制FMOPA <ZAda>.H, <Pn>/M, <Pm>/M, <Zn>.H, <Zm>.H
字段说明:
<ZAda>:目标ZA矩阵寄存器<Pn>/M, <Pm>/M:谓词寄存器,控制输入向量的有效元素<Zn>, <Zm>:源向量寄存器.H:表示半精度浮点格式指令编码中的几个关键控制位:
外积运算的数学表达式为:
code复制C = C ± A × B^T
其中:
指令执行时的硬件操作流程:
不同精度下的处理差异:
| 精度 | esize | ZA tile范围 | 典型应用场景 |
|---|---|---|---|
| FP16 | 16位 | ZA0-ZA1 | 机器学习推理 |
| FP32 | 32位 | ZA0-ZA3 | 科学计算 |
| FP64 | 64位 | ZA0-ZA7 | 高精度仿真 |
标准外积运算,输入输出精度一致:
assembly复制; FP32示例
FMOPA ZA0.S, P0/M, P1/M, Z0.S, Z1.S ; 累加模式
FMOPS ZA1.S, P2/M, P3/M, Z2.S, Z3.S ; 减法模式
支持从低精度输入计算高精度结果:
assembly复制; FP16->FP32扩展
FMOPA ZA0.S, P0/M, P1/M, Z0.H, Z1.H
扩展模式特点:
assembly复制; 计算C += A*B^T
FMOPA ZA0.S, P0/M, P1/M, Z0.S, Z1.S
FMOPA ZA0.S, P0/M, P1/M, Z2.S, Z3.S
assembly复制; 同时计算4个外积
FMOPA ZA0.S, P0/M, P1/M, {Z0.S-Z3.S}, {Z4.S-Z7.S}
在代码中应进行特性检测:
assembly复制MRS x0, ID_AA64SMFR0_EL1
TST x0, #(1<<8) ; 检查FEAT_SME_F16F16
B.EQ not_supported
assembly复制// 假设:A(MxK), B(KxN), C(MxN)
matrix_multiply:
MOV x0, #0 // 初始化行计数器
row_loop:
MOV x1, #0 // 初始化列计数器
col_loop:
// 加载A的行向量到Z0-Z3
// 加载B的列向量到Z4-Z7
FMOPA ZA0.S, P0/M, P1/M, Z0.S, Z4.S
FMOPA ZA0.S, P0/M, P1/M, Z1.S, Z5.S
FMOPA ZA0.S, P0/M, P1/M, Z2.S, Z6.S
FMOPA ZA0.S, P0/M, P1/M, Z3.S, Z7.S
ADD x1, x1, #1
CMP x1, #N
B.LT col_loop
ADD x0, x0, #1
CMP x0, #M
B.LT row_loop
assembly复制MSR ZA, #1
assembly复制MSR SVCR, #1
assembly复制STR ZA, [x0]
利用PMU计数器分析指令吞吐量
逐步增加向量长度测试可扩展性
典型场景下的性能指标(基于Arm Cortex-X5仿真):
| 运算类型 | 矩阵大小 | 吞吐量 (GOPS) |
|---|---|---|
| FP16外积 | 128x128 | 256 |
| FP32外积 | 64x64 | 128 |
| FP64外积 | 32x32 | 64 |
这些数据展示了SME扩展在矩阵运算方面的显著优势,特别是在FP16精度下性能最佳。