Add BMM_Theory: docs/02_分支理论/06_ASW_Basic分支.md

This commit is contained in:
2026-09-03 09:25:50 +00:00
parent 8664dd5e57
commit 47064c22de

View File

@@ -0,0 +1,131 @@
# ASW_Basic 分支理论(含尾轮处理)
> 整理自《BMM算子优化分析 v0.98》§八 + 《BMM尾轮处理策略对比分析 v1.5》.
> 尾轮策略的完整推导见 [07_尾轮处理策略.md](07_尾轮处理策略.md), 本文将其结论**内化为 ASW_Basic 最优实现的必要环节**.
> 对应软件实现: `bmm_theory/branches/asw_basic.py`.
## 1. 定位:兜底分支,实践中最常命中
ASW_Basic 是 BMM 的**兜底分支**——核间切 M/N或混合切不做 batch 合并或 K 维切分。能进入更靠前特殊分支转Matmul/特殊/MergeBatch/IterBatch/StreamK的 case 会被优先截胡剩下的都落到这里。v0.98 §十统计:对数采样下 ASW_Basic 占 54.1%是命中最多的分支。B 可大可小可等 1交叉广播也由此承接。
## 2. 进入条件
| # | 条件 | 说明 |
|---|---|---|
| 1 | `P = B·M·N·4B / L0C ≥ C` | **并行度补齐**:以 L0C 满载为基本块粒度B×M×N 能切出至少 C 个独立输出块 |
| 2 | 无 batch 结构限制 | BatchA=BatchB、交叉广播均可广播侧做 L1/L2 驻留,共享关系与切 M/N 同构) |
| 3 | **降核模式**`P < C` 且不满足 StreamK 进入条件 | 只用 ⌈P⌉ 个核,其余核闲置 |
**降核的理性**P < C K 也不够格走 StreamK 与其强行把 M/N 切得更碎tile 跌破 min_TileSizedValue 跌破 128B搬移效率崩塌反而更慢不如只用 P 个核每核一个 L0C 满载输出块这类 case 时延绝对值小继续切分的调度与搬移效率损失大于并行收益
## 3. 时延建模
核间切 M/N不切 K每核处理若干 [singleCoreM, singleCoreN] 输出块
$$T = \max(T_{MTE2},\; T_{MMAD},\; T_{FIX}) + T_{drain}$$
其中 `T_MMAD = 2BMNK/(C·Q16)``T_FIX = B·MN·outB/(C·W_pc)` 与分配策略无关——**分配策略只影响 T_MTE2**通过 L2 命中率影响有效 GM 带宽
$$T_{MTE2} = \frac{S_{in}^{GM}}{C\cdot BW_{pc}},\qquad S_{in}^{GM} = r_{in}\cdot S_{in}$$
`r_in` = 重复读倍率GM 输入流量/输入总量r_in1下界 1 表示每字节只从 GM 读一次后续复用全命中 L2)。**分配策略的全部目标就是让 r_in 尽量接近 1**。
## 4. 核间分配策略B→M→N 线性映射
**结论B 优先分组在任何场景下都不优于线性映射**根本原因
1. L2 是共享 Cache工作集越小命中率越高——线性映射同一时刻只激活 1 batch 的数据工作集最小
2. swizzle 窗口 W 参与核数——更多核参与同一 batch swizzle窗口更大工作集更接近"方形"下限
3. 线性映射对 B C 的关系无要求B 不整除 C 时无负载不均
数值例C=32、B=4、sM=sN=256、K=1024、BF16分组工作集 12MB线性 6MB——**线性映射工作集是分组的一半**。
## 5. 实现方案
**Step 0: BaseM/BaseN**L0 tile先把 L0C 用满
$$\text{BaseM}\times\text{BaseN} = \frac{L0C}{2\times 4B} = 32768\ \text{元素}$$
双缓冲两份FP32 4B/元素长宽比跟随 SingleCoreM/N对齐 16baseK = min(L0A/(2·BaseM·dt), L0B/(2·BaseN·dt)) 向下 16 对齐L1L0 dValue 要求)。
**Step 1: SingleCoreM/N**每核输出 tile,≥ BaseM/N
不受 L0 容量直接约束内部由若干 BaseM×BaseN L0 tile 组成)。核心影响 **GM→L1 搬移效率和 L2 重复读率**
- 约束 1 并行度`mCnt×nCnt ≥ ⌈C/B⌉`
- 约束 2 L1 容量`2(sM+sN)·k_L1·dt ≤ L1``k_L1·dt ≥ 256B`
- 约束 3 搬移效率`sM·k_L1·dt ≥ 16KB``k_L1·sN·dt ≥ 16KB`
- 约束 4SingleCoreM/N BaseM/N 的整数倍
选取策略满足约束 1 前提下 SingleCoreM/N 尽量大长宽比跟随 M/N
**Step 2: mCnt/nCnt 与核间分配**`mCnt=⌈M/sM⌉``nCnt=⌈N/sN⌉`总块数 B·mCnt·nCntBMN 线性映射
**Step 3: 切分维度选择(按共享代价从低到高)** B零共享先试)→ M右矩阵 L2 则驻留)→ N对称)→ 混合切 降核
**Step 4: swizzle——ASW 滑窗蛇形**
同一波 C 个核所需的 A 行块 + B 列块集合是"活跃工作集" L2 就回 GM swizzle 编排输出块执行顺序把每一波的活跃工作集压到最小窗口宽度 `W = max{d | d|C, d ≤ ⌊√C⌋}`C=32 W=4窗口内先扫 M扫满 W 行进下一列 N奇数窗口行 N 向反向蛇形)。
**Step 5: L2 分组(工作集超 L2 时)**
S_in = B(MK+KN)·dtS_out = B·MN·outB两个不变量GM 流量下界 = S_in + S_outL2 读入可用空间 L2_read = L2 S_out^resident
| 场景 | 条件 | 策略 |
|---|---|---|
| A 全驻留 | S_in + S_out L2 | 输入读一遍r_in=1输出驻留 L2 异步回写无需切分 |
| B 输入能驻留加输出超了 | S_in L2 < S_in+S_out | **输入驻留、输出直写 GM**保住 r_in=1校验总线 (S_in+S_out)/T_MMAD W_GM |
| C 输入本身超 | S_in > L2 | 分组执行,每组输入工作集 ≤ L2输出直写 GM |
场景 C 分组:每组覆盖 M 向 m_grp、N 向 n_grp 个基本块,`m_grp = ⌊D/(2·sM)⌋``n_grp = ⌊D/(2·sN)⌋`D = L2/(B·K·dt);重复读倍率 `r_in = (n_grp·M + m_grp·N)/(M+N)`。块内错位分核(对角线分配)避免同地址并发读串行化。
**Step 6: 核内 tiling**BaseM×BaseN×4B×DB ≤ L0CBaseM×k_L0×dt×2 ≤ L0Ak_L0×BaseN×dt×2 ≤ L0B内轴按 dValue 256B/512B 对齐。
**Step 7: 内部特化**:单边无 batch 且该侧矩阵小时小侧整个常驻 L1 只搬一次。
**Step 8: 降核模式**`usedCoreNum = ⌈P⌉`SingleCoreM/N 在 L0C 容量内取最大,每核标准核内流水,无需 swizzle 与 L2 切分。
## 6. 尾轮处理ASW_Basic 最优实现的必要组成)
总块数 `N_blk = B·mCnt·nCnt` 一般不是 C 的整数倍,尾轮只有 `r = N_blk mod C` 个核工作、Cr 核空转一个整块时间。**尾轮策略不是可选优化,而是 ASW_Basic 最优实现的必要组成**——首轮切分决定主轮效率,尾轮策略决定尾轮是否拖后腿。
### 6.1 候选策略
| 策略 | 做法 | tile 套数 |
|---|---|---|
| **A0 不重切** | 尾轮 r 核各处理 1 整块Cr 核空转 | 1 |
| **A1a 尾轮整数倍切分** | 尾轮每块沿 N或 M切 s* 份 | 2 |
| **A1b 尾轮 tile 重选凑满核** | 尾轮 r 个原块区域用更小 tile 重切,凑满 C 核 | 2 |
| **方案 B 整轮均匀重切** | 总块数向上取整到 n_wave·C全局统一 tile | 1 |
### 6.2 最优选择规则(融入方案生成)
依据主导项的**缩放类型**(面积型 ∝ sM·sN / 周长型 ∝ sM+sN判定见 07 文档 §2
**主流场景面积型主导prefill/decode 均属此类)**
- A1b 与方案 B **理论时延严格相等**(总量守恒 `T = c·B·M·N/C`
- **默认选方案 B工程简洁一套 tile、无尾轮分支**;追求搬移下限选 A1b周长和恒 ≤ 方案 B均值不等式
- r 小(ρ < (187/s)²)时 A1b 尾轮翻出为周长型,**方案 B 微优 ~6%**
- A1a 是 A1b 真子集,仅在 r | C 且 s*=⌊C/r⌋ 完美时打平,工程上可不单列。
**边角场景(周长型主导,小 tile 或工作集超 L2 的 GM 直读)**
- ρρ_dv=(256B/(sN·dt))²)时 **A1b 恒优**
- ρ < ρ_dv 且方案 B 可行且 `√ρ_dv > n_wave/√g (n_wave1)` 时方案 B 反超
- 广义方案 B允许核利用 80%恒不劣于 A0但恒不优于 A1b
**统一裁决**软件实现中对每个 case 07 文档 §6 的五步闭式流程计算**默认输出方案 B主流安全工程简洁周长型且 ρρ_dv 时输出 A1b**r=0 A0A0 永不最优r>0 时严格劣)。
### 6.3 软件结构体落位
尾轮参数落在 `ImplPlan` 的 tail_* 成员(参考源码 `MatMulV3TailInfo{mCnt,nCnt,kCnt,mTailMain,nTailMain}`
- `tail_strategy`A0 / A1a / A1b / 方案B
- `tail_m_cnt`/`tail_n_cnt`/`tail_k_cnt`尾轮切分数A1b 时为尾轮重切后的 mCnt'/nCnt'
- `tail_m_main`/`tail_n_main`:尾轮主体块数;
- `tail_block_cnt` = r`tail_wave_num` = n_wave。
## 7. 与源码的差异
源码 ASW 的核间分配用 `UpdateBasicIndex` 线性映射 + ASW 滑窗蛇形(与理论一致),但**尾轮不重切**`if (index < totalCnt)` 跳过空转核,即策略 A0。理论证明 A0 在 r>0 时严格劣于 A1b/方案 B——这是源码相对理论最优的一个明确差距点。本软件按 v1.5 的闭式决策流程输出尾轮策略,补齐这一差距。