v1.0: MergeBatch vs IterBatch 专项对比分析

This commit is contained in:
2026-08-26 11:05:56 +00:00
parent 16b37ebc9e
commit 6b03624de3

View File

@@ -0,0 +1,227 @@
# MergeBatch vs IterBatchBMM 小 tile 场景的两种实现路径分析
> 目标芯片:昇腾 950PRDAV_3510。理论分析基于《BMM 算子优化分析 v0.96》,源码参考 [cann-ops-nn](https://gitee.com/ascend/cann-ops-nn) 中 `matmul/batch_mat_mul_v3` 实现。
---
## 一、问题定义
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 tile**BaseM × 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 = BatchB$ 且 $b_{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 4$b_{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 核心差异GM→L1 搬移粒度
从 kernel 侧源码可直接观察:
- **IterBatch**`block_mmad_iterbatch.h` CopyInA1`ndNum = curIterBatchL1`(多块独立寻址,`srcNdMatrixStride = M*K`
- **MergeBatch**`block_mmad_mergebatch.h` CopyInA1`ndNum = 1`(合并为单块连续搬移,`nValue = b0 × M`
每次 GM→L1 DMA 搬移有固定开销 $T_{cmd}$(描述符配置 + 地址生成 + 突发启动与搬移数据量无关。MergeBatch 把 $b_0$ 次搬移合并为 1 次,$T_{cmd}$ 节省 $b_0$ 倍。
### 4.2 分情形分析
**K 截断情形**$k_{L1} = K$,整个 K 装入 L1 一块):
IterBatch 每 batch 一次 GM→L1 搬移MergeBatch 每合并 batch 一次(覆盖 $b_0$ 个 batch搬移次数少 $b_0$ 倍:
$$
\Delta_K = \underbrace{(b_0-1)(T_{comp} + T_{write})}_{\text{drain 惩罚}} - \underbrace{b_{core}\Big(1-\frac{1}{b_0}\Big) T_{cmd}}_{\text{搬移命令节省}}
$$
**L1 绑定情形**$k_{L1} < K$K 需分块
MergeBatch 合并后 tile 更大 $k_{L1}^m = k_{L1}/b_0$ $n_K^m = b_0 \cdot n_K$。搬移次数相同$b_{core} \cdot n_K$每次搬移量也相同——**MergeBatch 无搬移优势**只剩 drain 惩罚
$$
\Delta_L = (b_0-1)(T_{comp} + T_{write}) > 0
$$
**L1 绑定情形 MergeBatch 恒劣于 IterBatch**
### 4.3 统一分界条件
$$
\text{MergeBatch 最优} \iff k_{L1} = K \;\land\; b_{core} > \frac{b_0 \cdot (T_{comp} + T_{write})}{T_{cmd}}
$$
即 MergeBatch 仅在 **K 截断**(小 M/N 使 $L1/(2(M+N) \cdot dtype) \ge K$)且 $b_{core}$ 足够大时才优于 IterBatch。
| 维度 | IterBatch | MergeBatch | 差异 |
|---|---|---|---|
| 稳态搬移吞吐 | 相同 | 相同 | 总搬移量相同 |
| GM→L1 搬移命令数 | $b_{core}$ 次 | $b_{core}/b_0$ 次 | **MergeBatch 少 $b_0$ 倍** ← 核心优势 |
| drain 暴露 | $T_{comp} + T_{write}$ | $b_0(T_{comp} + T_{write})$ | IterBatch 少 $b_0$ 倍 ← 核心劣势 |
| L0C 利用率 | 低 | 高 | 访存 Bound 下不影响时延 |
### 4.4 $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 条件**
```cpp
// 源码https://gitee.com/ascend/cann-ops-nn
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 条件**
```cpp
// 源码https://gitee.com/ascend/cann-ops-nn
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 架构白皮书](https://public-download.obs.cn-east-2.myhuaweicloud.com/ascend/%E6%98%87%E8%85%BE950%20NPU%E6%9E%B6%E6%9E%84%E7%99%BD%E7%9A%AE%E4%B9%A6.pdf)华为技术有限公司2026
2. [CANN AscendC 算子开发——Matmul 高阶 API 使能 UnitFlag](https://www.hiascend.com/document/detail/zh/canncommercial/850/opdevg/Ascendcopdevg/atlas_ascendc_best_practices_10_10003.html)CANN 8.5.0
3. [cann-ops-nn 源码仓](https://gitee.com/ascend/cann-ops-nn)`matmul/batch_mat_mul_v3` 目录