v0.94: ASW_Basic L2切分改用singleCoreM/N+执行组概念,去除mL2/nL2

This commit is contained in:
2026-08-26 03:55:23 +00:00
parent 44178b6175
commit 862e816c41

View File

@@ -485,7 +485,7 @@ C=32 时 $\sqrt{32} \approx 5.66$,因子 {1,2,4,8,…} 中不超过它的最
**3、L2 切分(工作集超 L2 时)**
**切的是什么**L2 切分切的是**输出平面**—— M×N 平面切成 mL2TileNum × nL2TileNum 个大矩形块每块 = 若干基本块的集合),使"该块所需的 A 行带 + B 列带"输入工作集 L2 可用读入空间内所有输出基本块算完再进下一输入只在跨时换一次
**切的是什么** mCnt×nCnt 个基本块划分为若干**执行组**——每组覆盖输出平面上一个连续矩形区域若干 singleCoreM × singleCoreN 基本块的集合使该组所需的 A 行带 + B 列带输入工作集 L2 可用读入空间内所有基本块算完再进下一输入只在跨时换一次
**为什么需要它**滑窗压缩的只是"同一波"的足迹若整个工作集超 128MB L2跨波次复用落空——上一波窗口的 A 行早被挤出下一波又得回 GM L2 **读写共用**输出经 fixpipe 写出时若驻留 L2dirty会压缩读入可用空间若直写 GM则占用与读共享的 1.6TB/s 总线所以 L2 切分必须与写出策略联合决策记输入总量 $S_{in} = B(MK+KN)\cdot\text{dtype}$输出总量 $S_{out} = B \cdot MN \cdot outB$。
@@ -517,35 +517,40 @@ $$
B=8、M=N=4096、K=512、BF16——$S_{in}$≈67MB ≤ L2$S_{out}$≈268MB 直写 GMT_MMAD≈318µs总流量速率 (67+268)MB/318µs ≈ 1.05TB/s < 1.6TB/s ✓。
**场景 C$S_{in} > L2$(输入本身超)**必须 L2 切分输出直写 GM 以最大化 $L2_{read}$
**场景 C$S_{in} > L2$(输入本身超)**需要分组执行—— mCnt×nCnt 个基本块划分为若干**执行组**每组内所有基本块的输入工作集不超过 L2 可用空间输出直写 GM不占 L2 读入空间
**mL2 / nL2 的确定方法**
**L2 的软件可控手段**L2 Cache 而非 Buffer软件无法精确控制"哪些数据在 L2 "。可用的控制手段
- **Cache Hint**`SetL2CacheHint`标记输入为 allocate读入 L2 non-allocate直读 GM 不过 L2标记输出为 non-allocate直写 GM 不占 L2
- **CMO**Cache Maintenance OperationPrefetch/Writeback/Invalidate在关键节点主动管理 L2 内容
- **执行顺序**swizzle通过编排基本块的执行顺序控制同一时刻的活跃工作集——**这是最主要的 L2 管理手段**。
*问题* M×N 输出平面切成 mL2 × nL2 个大矩形块每块内所有输出基本块所需的输入工作集A 行带 + B 列带跨全部 B batch $L2_{read}$。
**执行组的划分**
*每块输入工作集*L2 $(i,j)$ 覆盖 M $M/mL2$ N $N/nL2$ 该块需要读入的 A 数据 = $B \times (M/mL2) \times K \times dtype$B 数据 = $B \times K \times (N/nL2) \times dtype$。合计
*问题*mCnt×nCnt 个基本块每块输出 singleCoreM×singleCoreN按什么粒度分组使每组的输入工作集 L2
*每组输入工作集*一组覆盖 M $m_{grp}$ 个基本块N $n_{grp}$ 个基本块即覆盖输出区域 $[m_{grp} \cdot \text{singleCoreM},\; n_{grp} \cdot \text{singleCoreN}]$。该区域需要读入的输入
$$
WS_{block} = B \cdot K \cdot \Big(\frac{M}{mL2} + \frac{N}{nL2}\Big) \cdot \text{dtype} \;\le\; L2_{read}
WS_{grp} = B \cdot K \cdot \big(m_{grp} \cdot \text{singleCoreM} + n_{grp} \cdot \text{singleCoreN}\big) \cdot \text{dtype} \;\le\; L2
$$
*目标*最小化 mL2×nL2数越少输入从 GM 的重复读次数越少)。块间输入重复读倍率
*目标*最小化数越少输入从 GM 的重复读次数越少)。每行 A $n_{grp}$ 个组各读一次每列 B $m_{grp}$ 个组各读一次
$$
r_{in} = \frac{nL2 \cdot MK + mL2 \cdot KN}{MK + KN}
r_{in} = \frac{n_{grp} \cdot M + m_{grp} \cdot N}{M + N}
$$
每行 A nL2 个块各读一次每列 B mL2 个块各读一次)。
*求解*约束 $M/mL2 + N/nL2 \le D$其中 $D = L2_{read}/(B \cdot K \cdot \text{dtype})$最小化 $nL2 \cdot M + mL2 \cdot N$。由拉格朗日乘子法最优在 $mL2/nL2 = M/N$ 时取到——**L2 切分比例应与输出平面形状成正比**。代入约束
*求解*约束 $m_{grp} \cdot \text{singleCoreM} + n_{grp} \cdot \text{singleCoreN} \le D$其中 $D = L2/(B \cdot K \cdot \text{dtype})$最小化 $n_{grp} \cdot M + m_{grp} \cdot N$。最优在组内 M/N 向基本块数与输出平面形状成正比时取到
$$
mL2 = \Big\lceil \frac{2M}{D} \Big\rceil,\qquad nL2 = \Big\lceil \frac{2N}{D} \Big\rceil,\qquad D = \frac{L2_{read}}{B \cdot K \cdot \text{dtype}}
m_{grp} = \Big\lfloor \frac{D}{2 \cdot \text{singleCoreM}} \Big\rfloor,\qquad n_{grp} = \Big\lfloor \frac{D}{2 \cdot \text{singleCoreN}} \Big\rfloor
$$
**与 L1 切分的关系**mL2/nL2 mL1/nL1 **独立**——L1 切分由 L0C 容量和 dValue 决定核内基本块尺寸L2 切分由 L2 容量和输入工作集决定块间复用粒度)。两者不要求相等或成倍数关系工程实现时L2 块边界应对齐到基本块边界mL2 整除 mL1nL2 整除 nL1避免跨块碎块
总组数 $= \lceil mCnt/m_{grp} \rceil \times \lceil nCnt/n_{grp} \rceil$
*例*B=64、M=N=2048、K=1024、BF16、$L2_{read}$=128MB$D = 128\text{MB}/(64 \times 1024 \times 2\text{B}) = 1024$。$mL2 = \lceil 2 \times 2048/1024 \rceil = 4$$nL2 = 4$。 4×4=16 每块工作集 $64 \times 1024 \times (512+512) \times 2 = 128\text{MB} = L2_{read}$恰好装满重复读倍率 $r_{in} = (4 \times 2048 \times 1024 + 4 \times 1024 \times 2048)/(2048 \times 1024 + 1024 \times 2048) = 4$
**组内 swizzle**每组内部按 ASW 滑窗蛇形执行窗口 $W = \max\{d \mid d \mid C,\; d \le \lfloor\sqrt{C}\rfloor\}$C=32 W=4保证同一波 C 个核的活跃工作集最小组间切换时输入整体换入——上一组的 A 行带和 B 列带全部失效 GM 重新读入下一组的数据
*例*B=64、M=N=2048、K=1024、BF16、singleCoreM=singleCoreN=256$S_{in} = 64 \times (2048 \times 1024 + 1024 \times 2048) \times 2 = 537\text{MB} > 128\text{MB}$。$D = 128\text{MB}/(64 \times 1024 \times 2\text{B}) = 1024$ 元素。$m_{grp} = \lfloor 1024/(2 \times 256) \rfloor = 2$$n_{grp} = 2$。每组覆盖 $[512, 512]$ 的输出区域,工作集 $= 64 \times 1024 \times (512+512) \times 2 = 128\text{MB} = L2$,恰好装满。总组数 $= (2048/256/2)^2 = 16$。$r_{in} = (2 \times 2048 + 2 \times 2048)/(2048+2048) = 2$——每行 A 被读 2 次,每列 B 被读 2 次。
块内分配用**错位分核**(对角线分配):线性块号先取 mn 方向叠加随块号递增的相位偏移,使同一时刻各核落在 M×N 平面的不同对角线上——避免多核同一拍并发读同一行 A / 同一列 B 的同一地址同地址并发读会串行化等效带宽打折。例8 核、4×4=16 个基本块k0~k7 为核号):