Files
matmul-analysis/BMM算子优化分析_Release/MergeBatch_vs_IterBatch分析_v1.0.md

14 KiB
Raw Blame History

MergeBatch vs IterBatchBMM 小 tile 场景的两种实现路径分析

目标芯片:昇腾 950PRDAV_3510。理论分析基于《BMM 算子优化分析 v0.96》,源码参考 cann-ops-nn 实现。

摘要

BMM 中当 B ≥ C 时核间切 B 免费,核内有 IterBatch逐 batch和 MergeBatch合并 b_0 个 batch两种路径。本文从 GM→L1 搬移粒度差异出发,证明 MergeBatch 的核心优势是合并搬移减少 DMA 命令数(每次搬移有固定开销 $T_{cmd}$),核心劣势是 drain 暴露放大 b_0。分界条件MergeBatch 仅在 K 截断$k_{L1} = K$,小 M/Nb_{core} 足够大时优于 IterBatchL1 绑定情形($k_{L1} < K$MergeBatch 恒劣于 IterBatch。与源码对比发现:源码 MergeBatch 进入条件偏宽(缺搬移量/tile/算存比约束IterBatch 只覆盖 L1 形态 b缺 a/c/d


一、问题定义

BMMBatchMatMul当 B ≥ Cbatch 数 ≥ AIC 核数)时,核间切 B 是免费的——每核独立处理若干 batch无共享无依赖。核内的两种实现路径

  • IterBatch:逐 batch 处理——每 batch 独立搬入 L1、独立计算、独立写回
  • MergeBatch:合并处理——把 b_0 个 batch 的 A[M,K]@B[K,N] 合并为 [b_0M, K]@[K, b_0N] 的大矩阵乘,一次搬入 L1、一次计算、一次写回

核心问题:什么条件下 MergeBatch 优于 IterBatch


二、IterBatch 理论最优实现

2.1 执行模型

核间切 B每核 b_{core} = B/C 个 batch。核内逐 batch 做标准 Matmul

对每 batch i ∈ [0, b_core):
    GM→L1: 搬入 A_i[M, K] + B_i[K, N](或按 kL1 分块)
    L1→L0→Cube: 计算 C_i[M, N]
    Fixpipe: L0C→GM 写回 C_i

2.2 L1 驻留形态

IterBatch 按 L1 容量分四种形态v0.96 §六):

形态 条件 特征
a) 单 batch 全驻留 $b_{core}=1$(MK+KN) \cdot dtype \le L1 零重复读
b) 双 batch 乒乓 $b_{core}>1$2(MK+KN) \cdot dtype \le L1 batch 间流水掩盖
c) 一侧驻留+对侧切 K $MK \cdot dtype \le L1/2$(驻留侧) 驻留侧零重复读
d) 两侧都切 K 兜底 两侧都有 K 段级重复读

2.3 实现方案

  • L0 tileBaseM × BaseN 尽量用满 L0C32768 元素双缓冲baseK 由 L0A/L0B 容量决定
  • L1 tile:按形态选择 kL1须满足 $k_{L1} \cdot dtype \ge 256$BdValue
  • 流水fixpipe 开 unitflagbatch 间由 L0C 双缓冲自动交叠

三、MergeBatch 理论最优实现

3.1 执行模型

核间切 B同 IterBatch核内把 b_0 个 batch 合并计算:

对每合并组 g ∈ [0, b_core/b0):
    GM→L1: 搬入 A'[b0·M, K] + B'[K, b0·N](单次 DMAndNum=1
    L1→L0→Cube: 计算 C'[b0·M, b0·N]
    Fixpipe: L0C→GM 写回(只取对角块,丢弃交叉项)

交叉项 (b_0^2 - b_0) \cdot MN 被算出但丢弃——浪费比例 $(b_0-1)/b_0$。进入该分支的 case 必然访存 Bound条件 5 保证),浪费的算力被搬移时延掩盖。

3.2 进入条件

同时满足(b_0 = 最小合并数,取 2

  1. BatchA = BatchBb_{core} = B/C \ge 2b_0
  2. $2(b_0 M)(b_0 N) \cdot 4B \le L0C$(合并后输出放得下 L0C 双缓冲)
  3. $b_{core}(MK+KN) \cdot dtype \ge min_DatamountPerCore$(单核搬移量足够)
  4. $\max(MK, KN) \cdot dtype \ge min_TileSize$(搬移 tile 不太小)
  5. $2MN/(M+N) < R_{16}/b_0$(合并后仍访存 Bound

3.3 实现方案

Step 1合并数 b₀L0C + 算存比双上限)


b_0 = \min\Big(\sqrt{\frac{L0C}{2 \cdot MN \cdot 4B}},\; \frac{R_{16}(M+N)}{2MN},\; b_{core}\Big)

Step 2L0 级 K 粒度 $k_{L0}$(由 b₀ 和 L0A/L0B 决定)


k_{L0} = \min\Big(\frac{L0A}{2 b_0 M \cdot dtype},\; \frac{L0B}{2 b_0 N \cdot dtype}\Big) \text{ 向下 16 对齐}

Step 3L1 级 $k_{L1}$(先反推再截断)

先令 $b_{L1}^* = b_0$,由 L1 容量反推 $k_{L1}^*$


k_{L1}^* = \frac{L1}{2 \cdot b_0 \cdot (M+N) \cdot dtype}

然后取 $k_{L1} = \min(k_{L1}^*,; K,; 512B/dtype)$——不超过 KK 截断),也不超过 dValue 推荐值 512B。

Step 4b_{L1} 最大化


b_{L1} = \min\Big(\frac{L1}{2 \cdot k_{L1} \cdot (M+N) \cdot dtype},\; b_{core}\Big)

若 $k_{L1}^* > 512B/dtype$k_{L1} 被 512B 截断,省出的 L1 空间可容纳更多 batch$b_{L1} > b_0$),提升 batch 间流水深度。


四、MergeBatch vs IterBatch 分界分析

4.1 执行模型与符号定义

两分支的核间切分相同——B 维切分到 C 核,每核 b_{core} = B/C 个 batch核内不切 M/N。差异在核内 K 维处理和 GM→L1 搬移粒度:

  • IterBatch:逐 batch 处理。每 batch 的 A[M,K]+B[K,N] 作为独立 DMA 操作搬入 L1源码 ndNum = curIterBatchL1,多块独立寻址),然后在 L1 内逐 batch 计算
  • MergeBatch:合并处理。b_0 个 batch 的 A'[b_0 M, K]+B'[K, b_0 N] 合并为一个大矩阵,作为单次 DMA 操作搬入 L1源码 ndNum = 1,单块连续搬移),然后合并计算

符号表

符号 含义 表达式/取值
C AIC 核数 32
b_{core} 每核 batch 数 B/C
b_0 合并因子(单次合并的 batch 数) 由 L0C + 算存比双上限确定
k_{L1} L1 级 K 分块粒度 \min(K,\; L1/(2(M{+}N) \cdot dtype))
n_K K 分块数 \lceil K/k_{L1} \rceil
T_{load} 每 K 分块搬移时延 k_{L1}(M{+}N) \cdot dtype / BW_{pc}
T_{comp} 每 K 分块计算时延 2MN \cdot k_{L1} / Q_{16}
T_{write} 单 batch 输出写回时延 MN \cdot outB / W_{GM}
T_{cmd} 单次 GM→L1 DMA 搬移固定开销 描述符配置 + 地址生成 + 突发启动
BW_{pc} 单核 GM 带宽份额 W_{GM}/C = 50 GB/s
Q_{16} 单核 Cube BF16 峰值算力 486/32 ≈ 15.2 TFLOPS
W_{GM} GM 带宽 1.6 TB/s
outB 输出元素字节数 BF16 → 2B

4.2 端到端时延建模

L0C 双缓冲使 fixpipe 与 Cube 完全交叠,batch 边界无额外同步开销。两分支的差异仅来自 GM→L1 搬移次数和 drain 暴露。

IterBatch 时延(每核处理 b_{core} 个 batch每 batch n_K 个 K 分块):


T_{iter} = \underbrace{b_{core} \cdot n_K \cdot (T_{load} + T_{cmd})}_{\text{搬移(逐 batch每次含 } T_{cmd}\text{}} + \underbrace{T_{comp} + T_{write}}_{\text{末 batch drain}}

MergeBatch 时延(每核处理 b_{core}/b_0 个合并 batch每合并 batch n_K^m 个 K 分块):


T_{mb} = \underbrace{\frac{b_{core}}{b_0} \cdot n_K^m \cdot (T_{load}^m + T_{cmd})}_{\text{搬移(合并,每次含 } T_{cmd}\text{}} + \underbrace{b_0 \cdot (T_{comp} + T_{write})}_{\text{末合并 batch drain}}

其中 T_{load}^m 是合并后每 K 分块的搬移时延,n_K^m 是合并后的 K 分块数——两者的取值取决于 k_{L1} 是否截断(见下)。

合并后 K 分块粒度MergeBatch 合并 b_0 个 batch 后L1 中的 tile 变为 $[b_0 M, k_{L1}^m] + [k_{L1}^m, b_0 N]$。L1 容量约束:


2 \cdot k_{L1}^m \cdot b_0 \cdot (M+N) \cdot dtype \le L1 \Rightarrow k_{L1}^m = \min\Big(K,\; \frac{k_{L1}}{b_0}\Big)
  • K 截断$k_{L1} = K$k_{L1}^m = K 不减半,$n_K^m = 1$——整个 K 装入 L1 一块
  • L1 绑定$k_{L1} < K$k_{L1}^m = k_{L1}/b_0 减半,$n_K^m = b_0 \cdot n_K$——K 分块数 b_0

4.3 K 截断情形($k_{L1} = K$

$n_K = n_K^m = 1$$T_{load}^m = b_0 \cdot T_{load}$(合并后单次搬移数据量 b_0 倍):


T_{iter} = b_{core}(T_{load} + T_{cmd}) + T_{comp} + T_{write}

T_{mb} = \frac{b_{core}}{b_0}(b_0 \cdot T_{load} + T_{cmd}) + b_0(T_{comp} + T_{write})

两式相减:


\Delta_K = T_{mb} - T_{iter} = \underbrace{(b_0-1)(T_{comp} + T_{write})}_{\text{drain 惩罚}} - \underbrace{b_{core}\Big(1-\frac{1}{b_0}\Big) T_{cmd}}_{\text{搬移命令节省}}

分界条件MergeBatch 优于 IterBatch 当且仅当 $\Delta_K < 0$


b_{core} > \frac{b_0 \cdot (T_{comp} + T_{write})}{T_{cmd}}

小 MN → T_{comp} 小 → 惩罚小 → MergeBatch 更容易赢;大 B → b_{core} 大 → 搬移节省多 → MergeBatch 更容易赢。

4.4 L1 绑定情形($k_{L1} < K$

$k_{L1}^m = k_{L1}/b_0$$n_K^m = b_0 \cdot n_K$$T_{load}^m = T_{load}$(每块搬移量相同,因为 $k_{L1}^m \cdot b_0 = k_{L1}$


T_{iter} = b_{core} \cdot n_K \cdot (T_{load} + T_{cmd}) + T_{comp} + T_{write}

T_{mb} = \frac{b_{core}}{b_0} \cdot b_0 n_K \cdot (T_{load} + T_{cmd}) + b_0(T_{comp} + T_{write}) = b_{core} \cdot n_K \cdot (T_{load} + T_{cmd}) + b_0(T_{comp} + T_{write})

搬移次数相同($b_{core} \cdot n_K$),每次搬移量相同——MergeBatch 无搬移优势


\Delta_L = T_{mb} - T_{iter} = (b_0-1)(T_{comp} + T_{write}) > 0

L1 绑定情形 MergeBatch 恒劣于 IterBatch——合并只放大了 drain 暴露,没有换来搬移命令节省。

4.5 统一分界条件


\text{MergeBatch 最优} \iff \underbrace{k_{L1} = K}_{\text{K 截断}} \;\land\; \underbrace{b_{core} > \frac{b_0 \cdot (T_{comp} + T_{write})}{T_{cmd}}}_{\text{搬移节省} > \text{drain 惩罚}}

K 截断的物理含义:$L1/(2(M{+}N) \cdot dtype) \ge K$——小 M/N 使 L1 一次装下整个 K 维。

维度 IterBatch MergeBatch 差异
稳态搬移吞吐 相同 相同 总搬移量相同
GM→L1 搬移命令数 b_{core} b_{core}/b_0K 截断时) MergeBatch 少 b_0 ← 核心优势
drain 暴露 T_{comp} + T_{write} b_0(T_{comp} + T_{write}) IterBatch 少 b_0 倍 ← 核心劣势
L0C 利用率 访存 Bound 下不影响时延

4.6 T_{cmd} 的物理成因

每次 GM→L1 DMA 搬移的固定开销包括Nd2Nz 描述符配置ndNum/nValue/dValue/srcStride 等 7 个字段写入 DMA 寄存器)、地址生成与突发启动、与 L1 buffer 的同步握手(SetFlag<MTE2_MTE1> / WaitFlag<MTE1_MTE2>)。量级估计为数十 ns精确值需实测标定。


五、与源码实现的对比

5.1 MergeBatch 源码(batch_matmul_v3_mergebatch_basicapi_tiling.cpp

IsCapable 条件

// 源码https://gitcode.com/cann/ops-nn/tree/master/matmul/batch_mat_mul_v3
if (batchC < MIN_BATCH_L0 * aicNum) return false;  // B < 128即 b_core < 4
if (alignK < 64 || M > N) return false;             // K ≥ 64M ≤ N
if (L0 buffer check with b0=4) return false;        // L0C 容量

对比分析

维度 理论 源码 差异
合并数 b₀ min(L0C 上限, 算存比上限, b_core) MIN_BATCH_L0 = 4固定实际由多项式动态求解 源码 b₀=4 是硬编码下限,实际值由 L0C 容量动态计算
b_core 下限 ≥ 2b₀ = 4 ≥ 4batchC ≥ 128 一致
L0C 约束 2(b₀M)(b₀N)·4B ≤ L0C tempAlignM × tempAlignN × 4B × 2 ≤ L0C 一致
搬移量约束 b_core(MK+KN)·dtype ≥ 480KB 源码缺少
tile 大小约束 max(MK,KN)·dtype ≥ 16KB 源码缺少
算存比约束 2MN/(M+N) < R₁₆/b₀ 源码缺少
额外约束 K ≥ 64M ≤ N 源码独有

结论:源码的 MergeBatch 进入条件偏宽——缺少搬移量、tile 大小、算存比三条约束。可能导致不应进入的 case 被误捕获(如计算 Bound 的 case 进入 MergeBatch 后冗余计算成为瓶颈)。

5.2 IterBatch 源码(batch_matmul_v3_iterbatch_basicapi_tiling.cpp

IsCapable 条件

// 源码https://gitcode.com/cann/ops-nn/tree/master/matmul/batch_mat_mul_v3
if (batchC <= aicNum) return false;  // B ≤ 32 不进 IterBatch
if ((alignM*alignK + alignK*alignN)*dtype*2 > L1) return false;  // L1 双缓冲
if (!l0CanLoadBatch_ && balanceRate < 0.8) return false;  // 负载均衡

对比分析

维度 理论 源码 差异
L1 形态 四种a/b/c/d 只覆盖形态 b 源码缺 a/c/d
B 下限 b_core ≥ 1 B > 32b_core ≥ 2 源码排除了 b_core=1 的形态 a
负载均衡 B mod C ≥ minCoreNum balanceRate ≥ 0.8 实现方式不同,目的一致

结论:源码的 IterBatch 只覆盖形态 b(双 batch 乒乓),且要求 B > C。形态 a/c/d 的 case 由 ASW/AL1/BL1 分支承接。

5.3 综合评价

理论分析的价值在于:

  1. 分界条件——源码无显式 MergeBatch vs IterBatch 分界,理论给出了 k_{L1} = K \land b_{core} > b_0(T_{comp}+T_{write})/T_{cmd} 的闭式条件
  2. L1 绑定情形——理论证明 MergeBatch 在 L1 绑定时恒劣于 IterBatch源码未区分
  3. T_cmd 的物理意义——GM→L1 DMA 命令固定开销,是 MergeBatch 优势的本质来源

源码实现的价值在于:

  1. 工程完备性——负载均衡、格式检查、bias 处理等
  2. cubeBound 模型——经实测调优的 baseM/baseN 寻优
  3. L2 Cache 管理——100MB 阈值 + transConflict 控制

参考文献

  1. 昇腾 950 NPU 架构白皮书华为技术有限公司2026
  2. CANN 9.2.0-beta.1 Ascend C API 参考——UnitFlag 机制详见"矩阵计算ISASI/Mmad 计算关键特性说明/UnitFlag"章节
  3. cann-ops-nn 源码仓