From 5db73dfa263e63e584f18bdc0ba15596b0301c63 Mon Sep 17 00:00:00 2001 From: admin Date: Wed, 9 Sep 2026 11:53:39 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=96=B0=E5=A2=9E=2006=5F=E8=90=BD?= =?UTF-8?q?=E5=9C=B0=E9=AA=8C=E8=AF=81=E8=AE=A1=E5=88=92=5F=E7=90=86?= =?UTF-8?q?=E8=AE=BA=E6=96=B9=E6=A1=88=5Fvs=5Fbmmv3=E6=BA=90=E7=A0=81.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 理论方案落地 batch_mat_mul_v3 真实算子源码(arch35/Ascend950PR)的 比对分析与上板验证计划: - 源码现状架构梳理(host 策略注册表静态优先级/kernel 7 参模板分发/ 平台带宽算力公式与理论口径天然对齐) - 五分支逐项比对(StreamK/ASW 尾轮/IterBatch 形态/MergeBatch 准入仲裁/ 转Matmul特殊广播), 每项含差异清单+host/kernel 修改重点+ 预期时延变化(理论模型测算数字)+验证重点 - 收益排序: StreamK 准入放宽(定向 case -73%~-82%, host-only) > ASW 尾轮重切(-25%~-43%, 方案B host-only) > MergeBatch 准入补齐 (防误捕获) > IterBatch 形态补全(kernel 重写, 收益待 T_cmd 标定) - 上板验证方案(三层 case 集/标定项/通过标准)与分批 PR 计划 README 文档树补登 04/06 两篇。 --- BMM/BMM_Theory/README.md | 4 +- .../06_落地验证计划_理论方案_vs_bmmv3源码.md | 391 ++++++++++++++++++ 2 files changed, 394 insertions(+), 1 deletion(-) create mode 100644 BMM/BMM_Theory/docs/06_落地验证计划_理论方案_vs_bmmv3源码.md diff --git a/BMM/BMM_Theory/README.md b/BMM/BMM_Theory/README.md index f1ad30d..4635863 100644 --- a/BMM/BMM_Theory/README.md +++ b/BMM/BMM_Theory/README.md @@ -94,7 +94,9 @@ BMM_Theory/ │ │ ├── 06_ASW_Basic分支.md # 尾轮策略已内化为其必要环节 │ │ └── 07_尾轮处理策略.md # 尾轮完整推导 (参考) │ └── 03_测评报告/ # 外部测评报告 (v1.0/v2.0 及后续复评) -│ └── 05_L2驻留GM读写与dtype算力口径_设计分析.md # GM/L2/输出落点/dtype算力统一口径 (issue#27-#30) +│ ├── 04_差异对照_bmmv3_vs_BMM_Theory.md # bmmv3 行为预测器 vs 理论推导器对照 +│ ├── 05_L2驻留GM读写与dtype算力口径_设计分析.md # GM/L2/输出落点/dtype算力统一口径 (issue#27-#30) +│ └── 06_落地验证计划_理论方案_vs_bmmv3源码.md # 理论落地 bmmv3 源码的比对/修改/上板验证计划 ├── examples/ # 示例输入输出 └── tests/ # 单元测试 (固化文档边界 case + issue 回归) ``` diff --git a/BMM/BMM_Theory/docs/06_落地验证计划_理论方案_vs_bmmv3源码.md b/BMM/BMM_Theory/docs/06_落地验证计划_理论方案_vs_bmmv3源码.md new file mode 100644 index 0000000..e8913bd --- /dev/null +++ b/BMM/BMM_Theory/docs/06_落地验证计划_理论方案_vs_bmmv3源码.md @@ -0,0 +1,391 @@ +# 06 理论方案落地 batch_mat_mul_v3 源码 — 比对分析与验证计划 + +> 目的:把 BMM_Theory 的理论最优方案落到真实算子源码 `batch_mat_mul_v3`(ops-nn), +> 上板(**Ascend950PR 主 bin,arch35 / DAV_3510**)实测验证收益,达标后向真实算子源码仓提 PR。 +> 比对基线源码:`\\HwFs\HW_WorkBuddy\昇腾NPU\昇腾NPU知识库\代码仓\ops-nn\matmul\batch_mat_mul_v3` +> (下称"源码",行号为该仓当前快照);理论侧:本仓 `bmm_theory/` + `docs/02_分支理论/`。 +> 文中所有"预期收益"数字均为**理论模型测算**(含 T_cmd=0 等未标定假设),仅用于排优先级, +> 最终以 msProf 上板实测为准。 + +--- + +## 0. 结论摘要(TL;DR) + +| 优先级 | 分支/主题 | 源码现状一句话 | 理论差异一句话 | 模型预估收益(定向 case) | 改动面 | 建议批次 | +|---|---|---|---|---|---|---| +| P0 | **StreamK 准入放宽** | 固定 K≥8192 门槛,拒绝后落 ≤4 核 ASW | 动态 grid_K + θ_c≈10.9 归约代价判据(K>~360 起可进) | **总时延 −73%~−82%**(K=4096~6144 细长 case) | **纯 host tiling**(kernel 已有完整 StreamK 实现) | 批次 1 | +| P1 | **ASW 尾轮重切** | 尾轮 `index≥totalCnt` 空转(A0);ASW_BASIC 仅做单套 tile 的均衡率枚举 | 方案B(全局一套 tile 重切)/A1b(尾轮第二套 tile),A0 在 r>0 时严格劣 | **总时延 −25%~−43%**(2 波 + 尾轮 ρ=0.125~0.5 的 case) | 方案B 纯 host;A1b 需 kernel 读第二套尾轮参数(共享库有现成范式) | 批次 2 | +| P2 | **MergeBatch 准入补齐 + 仲裁接线** | 准入偏宽(缺搬移量/tile/算存比三条),且静态优先级恒先于 IterBatch | 理论 5 条件 + 与 IterBatch 的净收益仲裁(L1 绑定时 MergeBatch 恒劣) | 防误捕获(小搬移量 case 冗余计算/小 tile 低效);仲裁差异 T_cmd=0 下 ≤0.5% | **纯 host tiling** | 批次 3 | +| P3 | **IterBatch 形态补全(a/c/d)** | 仅"整 K 双侧驻留 + 双 batch 乒乓"(形态 b),放不下 L1 直接拒绝 → 落 ASW | 理论四形态(a 单 batch 驻留 / c 一侧驻留+对侧切K / d 两侧切K),k_l1 反推不受 512B 上限 | T_cmd=0 下 k_l1 差异本身 ≈0(<0.6%);收益=命令数 4× 减少 ×T_cmd + 消除 ASW 承接时的 L2 重复读 | **kernel 重写 mmad 流水(最难)** + host 准入 | 批次 4 | +| P4 | 转Matmul / 特殊分支 / 广播 | 已有 TO_MUL、K_EQ_ZERO、ITER_BATCH_BROADCAST、MergeBatchAndMAxis 折叠 | 理论基本一致(BatchA=1 大 A 的"重排转 Matmul"源码无,低优先) | 对齐核查即可 | 核查 | 随批附带 | + +**总体判断**:收益大头在 **StreamK 准入**与 **ASW 尾轮** 两处,且都可先做 **host-only** 改动拿到大部分收益; +IterBatch 形态补全改动最大、收益依赖 T_cmd 标定结果,放最后。 + +--- + +## 1. 源码现状架构速览(arch35 / DAV_3510) + +### 1.1 host 侧:策略注册表 + 静态优先级 + +`batch_mat_mul_v3_tiling.cpp`:`IsAdvancedSocVersion` → arch35 advanced 路径 +(`arch35/batch_matmul_v3_tiling_advanced.*`),按 `batch_matmul_v3_tiling_strategy.h` +的优先级表**逐策略试 `IsCapable()`,首个通过即中,无回退、无时延仲裁**: + +``` +K_EQUAL_ZERO(0) → TO_MUL(1) → STREAM_K(2) → MERGE_BATCH_BASICAPI(3) +→ ITER_BATCH_BROADCAST_BASICAPI(4) → ITER_BATCH_BASICAPI(5) → ITER_BATCH(6) +→ AL1_FULL_LOAD_BASIC(7) → BL1_FULL_LOAD_BASIC(8) → ASW_BASIC(9) → BASE(999) +``` + +与理论决策树(`router.py`)的结构差异: + +| 项 | 源码 | 理论 | +|---|---|---| +| 路由方式 | 静态优先级 + IsCapable 一票否决/通过 | 决策树 + 重叠区端到端时延模型仲裁 | +| StreamK vs 切B | StreamK **优先于** MergeBatch/IterBatch | 切B(B≥C)优先,StreamK 仅在 P≤C/2 | +| Merge vs Iter | MergeBatch 恒优先(无仲裁) | 净收益仲裁 + 时延模型终审 | +| 兜底 | ASW_BASIC(等 batch)/ BASE(广义,固定 256×256 起步) | ASW_Basic(含降核)恒出方案 | + +### 1.2 kernel 侧:7 参模板分发 + +`op_kernel/arch35/batch_mat_mul_v3.cpp:171` 起:模板参数 +``,`if constexpr` 链分发: +IterBatch(cmct `KernelMatMulIterBatch` / 旧库 `MultiBatchKernel` 两世代并存)、 +MergeBatch(cmct `KernelMatMulMergeBatch`)、ASW(`BatchMatMulAswKernel/AswBlock`)、 +StreamK(Blaze `MatMulStreamKKernel` 或内置 `MatMulStreamKActKernel`)等。 +**关键事实**:StreamK 的 kernel(动态 kCnt 调度、fp32 部分和、AIV 归约)**已完整存在**; +ASW 尾轮重切所需的 `MatMulV3TailInfo{mCnt,nCnt,kCnt,mTailMain,nTailMain}` 字段在 +`MatMulV3TilingData` 已存在(共享 mat_mul 的 `block_scheduler_aswt.h`/`mat_mul_asw_block.h` +有现成"尾 tile 再切子块"范式),**batch 版 AswBlock 只是没有读这些字段**。 + +### 1.3 口径天然对齐(好消息) + +源码 tiling 内的平台公式与理论硬件口径一致: +`GetHbmBW = freq×32×31/1024 ≈ 1.6TB/s`;`GetL2BW = freq×32×100/1024 ≈ 5.16TB/s ≈ 理论 5.2TB/s`; +`singleCoreComputePower = freq×8(K) ≈ 13.2T ≈ 理论 Cube-only 13.5T`(差 2%,经验取整)。 +→ 理论模型与源码 tiling 的"带宽/算力世界观"兼容,参数级差异小,差异集中在**策略结构**。 + +--- + +## 2. 分支逐项比对与修改重点 + +### 2.1 StreamK(P0,最大收益,host-only 可落地大半) + +**理论方案**(`docs/02_分支理论/05_StreamK分支.md`): + +- 进入:P = B·M·N·4B/L0C ≤ C/2;K/grid_K ≥ 256B/dtype;**K > grid_K²/(grid_K−1)·θ_c,θ_c≈10.9** + (grid_K=32 → K>360);确定性等级 ≤1 且 ND。 +- grid_K 动态:blocksPerBatch=⌊C/B⌋,grid_K=blocksPerBatch/(mCnt·nCnt),mCnt/nCnt 收拢为因子。 +- 部分和 fp32 写 workspace(防精度丢失),AIV 归约后按 C dtype 写出;workspace 应尽量驻留 L2 + (落 GM 时归约带宽 5.2→~0.64TB/s,θ_c 升至 ~86)。 + +**源码现状**(`arch35/batch_matmul_v3_basic_streamk_tiling.cpp`): + +- 准入 `CheckStreamKSKTiling`:**固定门槛 `CeilAlign(K,256) ≥ max(8192, aicNum×256B/dtype)`** + (bf16 即 8192);`batch·mCnt·nCnt ≤ aicNum/2`(mCnt/nCnt 按 256 估算);fp32 非 HF32 且 K>2e6 拒绝。 +- grid_K 已有动态雏形:`tailInfo.kCnt = ⌊aicNum/(batch·mCnt·nCnt)⌋`,`singleCoreK=⌈K/kCnt⌉` + (落盘 `skSingleCoreK`);mCnt/nCnt 有">blocksPerBatch/3 且 360(grid_K=32) | **K∈(360, 8192) 的细长 case 全部被拒绝**,落 ASW 只用 batch·mCore·nCore ≤ C/2 核 | +| S2 | 准入无"归约代价 vs 不切 K"比较(θ_c 判据) | 门槛同时承担了 dValue 与归约代价两职,过保守 | +| S3 | workspace 大小固定 `C×256×256×4B`(8MB+RPC) | 与 mCnt/nCnt/kCnt 实际解耦,偏大但不阻断 | +| S4 | mCnt/nCnt 启发式收拢 vs 理论"收拢为 blocksPerBatch 因子最大化 grid_K" | 参数级,影响 K 并行度 | +| S5 | workspace 显式 L2 驻留无法由 op 侧表达(只有 SetL2CacheHint) | 架构级,暂不做,靠 L2 自然缓存 | + +**修改重点(host-only,批次 1)**: + +1. `CheckStreamKSKTiling`:把固定 8192 门槛替换为**理论两条判据**—— + 先按现行逻辑试算 mCnt/nCnt/kCnt,然后要求 `K/kCnt ≥ 256B/dtype`(条件 2,dValue)且 + `K > kCnt²/(kCnt−1)·θ_c'`(条件 3,归约代价)。θ_c' 取 **GM 口径 ~86**(保守,workspace 名义 GM) + 或按 workspace ≤ L2 余量切换 L2 口径 10.9——建议第一版用 GM 口径(grid_K=32 时 K>~2841), + 上板测得归约段实际命中 L2 后再放宽。 +2. mCnt/nCnt 收拢规则替换为"blocksPerBatch 因子 + grid_K 最大化"(理论 §4)。 +3. 保持 kernel 不动(tiling 字段 `skSingleCoreK`/`tailInfo.kCnt` 语义不变)。 + +**预期时延变化**:减少的是 **MTE2 稳态段**(并行度 4→32 核)与 MMAD 段同比例; +新增有限的 **归约尾(t_reduce)**。模型测算(bf16): + +| case | 源码现状(ASW 降核,核数=batch·mCore·nCore) | 理论 StreamK | 总时延节省 | +|---|---|---|---| +| B=4, M=N=128, K=4096 | 41.9us(4 核) | 8.65us(steady 5.24 + reduce 3.41) | **−79.4%** | +| B=4, M=N=128, K=6144 | 62.9us(4 核) | 11.27us | **−82.1%** | +| B=8, M=256, N=128, K=4096 | 62.9us(8 核) | 16.60us | **−73.6%** | + +敏感性:若 workspace 实际走 GM 带宽(不命中 L2),K=4096 例 reduce 升至 ~10us,总 ~15.4us, +仍省 ~63%。**反向保护**:θ_c 判据保证 K 太小(归约吃不下)时不进——理论 K=2048 例即被判不可行。 + +**验证重点**: +- 定向 case 集:B∈{2,4,8},M/N∈{64,128,256},K∈{2048, 2843±, 4096, 6144, 8000, 8192±, 10240}, + 覆盖"源码拒绝→修改后进入"的跃迁区间与 θ_c 边界两侧(K∈{2841±} 附近加边界 case,验证不错进/不漏进); +- msProf 拆解:MTE2/MMAD 稳态是否如预期缩短,**归约段实测时延 vs 模型 3.4us(L2 口径)/~10us(GM 口径)** + —— 据此裁决 workspace 口径与 θ_c' 取值; +- 正确性:fp32 部分和 + AIV 归约的数值精度(对比 golden,deterministic_level=0/1); +- 回归:K≥8192 老 case 时延不回退(grid_K 推导变化的影响面)。 + +### 2.2 ASW_Basic 尾轮重切(P1,方案B 可 host-only) + +**理论方案**(`docs/02_分支理论/06_ASW_Basic分支.md` §6 + `07_尾轮处理策略.md`): +总块数 N_blk = B·mCnt·nCnt 不能整除 C 时,尾轮 r = N_blk mod C 个核干活、C−r 核空转一个整块。 +**A0(不重切)在 r>0 时严格劣**;面积型主导下 A1b(尾轮第二套小 tile 凑满核)与方案B(全局一套 +tile 均匀重切到 n_wave·C 块)理论时延严格相等 = (n_wave−1+ρ)·T_block;周长型且 ρ≥ρ_dv 时 A1b 恒优; +r 小翻出时方案B 微优 ~6%。软件默认输出方案B,周长型 ρ≥ρ_dv 输出 A1b。 + +**源码现状**: +- kernel `asw_kernel_advanced.h` Process:`if (index < totalCnt)` 才干活,**尾轮 C−r 核真空转(A0)**; +- host `ASW_BASIC` 的 `GetRebalanceBlock`(`mat_mul_v3_tiling_helper.cpp:387`)枚举 baseM/baseN + 最大化"均衡率",**但 `GetBalanceRateWithTail` 里尾轮切分项在 `batchInfo != nullptr` 时被禁用** + (:240 早退),即 batch 场景的均衡率按 A0 模型算——枚举只隐式接近"广义方案B",且无 + "搬入最小化"目标与尾轮翻出概念; +- `BASE` 策略(广播/非等 batch 兜底)连 GetRebalanceBlock 都没有,固定 baseM=baseN=256 + A0。 + +**差异清单**: + +| # | 差异 | 影响 | +|---|---|---| +| T1 | 尾轮空转(A0) | r>0 时白丢 (1−ρ)/n_wave 比例的总时延 | +| T2 | 首轮 tile 枚举目标=均衡率/cubeBound 启发式 vs 理论"每 batch 搬入 K·dt·(nCnt·M+mCnt·N) 最小 + 尾轮 r 最大 tie-break" | L2 重复读量、dValue 效率差异 | +| T3 | 无 A1b(尾轮第二套 tile) | 周长型主导区少拿 A1b vs 方案B 的差 | +| T4 | 无降核口径对齐:源码 usedCoreNum=min(batch·mCore·nCore, C) vs 理论 P=L0C 满载粒度降核 | 并行度估计口径不同,需上板对齐 | + +**修改重点**: +1. **方案B(host-only,先做)**:`GetRebalanceBlock` 之后追加"整轮均匀重切"——由 N_blk、n_wave、r + 计算 g = n_wave·C/N_blk,把 baseM/baseN 在候选集内按 1/√g 收缩重选(或直接在枚举目标函数里 + 把 A0 均衡率换成 `w×T_block` 估计),使尾轮满载。kernel 零改动(一套 tile,totalCnt 变为 + n_wave·C,天然无空转)。 +2. **A1b(kernel 配合,后做)**:host 计算第二套尾轮 tile 参数写入 `MatMulV3TailInfo` 现有字段; + `asw_block_advanced.h` 的 Init/UpdateBasicIndex/UpdateBlockParams/CalcGMOffset 按 roundIdx + 切换主/尾相位——**直接移植共享库 `block_scheduler_aswt.h` 的尾 tile 子块范式**(mTailCnt/nTailCnt + 现成字段),保持每子片单核单写(不引入跨核归约)。纯运行期数据驱动,**不增编译变体**。 +3. 尾轮策略选择逻辑(A0/A1b/方案B 的五步闭式判定)放在 host,输出到 tiling 备注字段便于验证对照。 + +**预期时延变化**:减少的是 **drain/尾轮段**((1−ρ)·T_block 量级),即 max 稳态之后的空转暴露。 +模型测算(理论 ASW evaluate,强制 A0 vs 最优尾轮): + +| case | N_blk / 波次 / ρ | A0(源码现状) | 最优尾轮 | 总时延节省 | +|---|---|---|---|---| +| B=2, M=1024, N=1536, K=1024 | 48 / 2 / 0.50 | 19.88us | 14.91us(方案B) | **−25.0%** | +| B=2, M=1024, N=1280, K=1024 | 40 / 2 / 0.25 | 19.88us | 12.43us(方案B) | **−37.5%** | +| B=2, M=768, N=1536, K=1024 | 36 / 2 / 0.125 | 20.04us | 11.34us(方案B) | **−43.4%** | + +(同为 MMAD/MTE2 主导的面积型 case;周长型边角区 A1b 另有收益,量级待 case 库扫描。) +注意:源码 ASW_BASIC 的均衡率枚举已能自发吸收其中一部分(相当于不完整的方案B), +**实测基线必须先跑**,预期净收益 = 表值 − 源码枚举已拿到的部分;BASE 兜底命中的 case +(广播、非等 batch)则全额可期。 + +**验证重点**: +- 定向构造 N_blk mod C ≠ 0 且 n_wave ∈ {1,2,3,≥4} 的 case 矩阵(B∈{2,3,5,6} × M/N 组合扫描), + 确认尾轮核不再空转(msProf 核间时间线/各核结束时刻拉齐); +- 对比维度:总时延、尾轮起止时刻、GM/L2 流量(方案B tile 变小 → 搬入周长和 √g 放大, + 理论已标注 P4 流量放大不入模型,**需实测是否吞掉收益**——这是该改动的头号验证风险); +- 正确性:尾轮重切后边界块(mBaseTail/nBaseTail)数值正确性; +- 回归:r=0 的 case 零变化(应自动保持 A0)。 + +### 2.3 IterBatch 形态补全(P2/P3,kernel 重写流水,收益依赖 T_cmd 标定) + +**理论方案**(`docs/02_分支理论/02_IterBatch分支.md`):核间切 B 后,核内按 L1 容量四形态选一—— +a) 单 batch 全驻留(b_core=1);b) 双 batch 乒乓(2(MK+KN)·dt ≤ L1,命中最多); +c) 一侧驻留+对侧切 K(驻留侧 ≤ L1/min(b_core,2),b_core≥2 时另一半 L1 预取下一 batch 驻留侧); +d) 两侧都切 K(兜底,K 段成对流水)。四形态共同保证**单 batch 计算核内零重复读、GM=V_in**; +k_l1 按容量反推(不受 512B 硬上限,dValue≥128B 下限约束)。 + +**源码现状**: +- `iterbatch_basicapi_tiling.cpp` IsCapable:`batchC > aicNum`(严格 B>C)+ + **`2×((M·K+K·N)·dt+bias) ≤ L1`**——即只有形态 b;放不下直接 false(或 L0 放不下单 batch 时走 + 0.8 均衡率兜底),**无 c/d 形态的退化承接**; +- kernel(cmct `BlockMmad` IterBatch 偏特化)实证:L1 布局=整 K 的 A/B 各 2 缓冲按 batch 叠放, + L1→L0 才按 baseK 切 K,mmad 循环 iter1(batch)→N→M→K;**代码中不存在"一侧驻留+对侧切K"或 + "两侧切K"的显式模式**;`mmadParams.unitFlag` 恒 0(理论假设的 UnitFlag 16-granule 细粒度流水 + 在该路径未启用);写回 L0C→GM 直写(ON_THE_FLY)或经 UB/AIV(ND_FIXPIPE_1_2),不经 L2。 + +**形态 c/d 的 case 在源码里的实际去向**:落 ASW_BASIC/BASE——ASW 把 M/N 切到 ≤256 的 base 块、 +K 由 L1 tiling 切,共享块重复读走 L2。**不是灾难,但偏离理论最优**: +1. M/N>256 时被切块 → 引入 (nCnt−1)·a_b+(mCnt−1)·b_b 的 L2 重复读(理论 IterBatch 为 0); +2. K 粒度受 512B 内轴对齐与 stepK≤8(issue queue)限制,单命令 tile 更小、命令数更多; +3. 无 batch 边界预取(理论 c 形态半预算预取驻留侧,边界无气泡)。 + +**模型测算**(形态 d 例:B=64, M=N=64, K=8192, bf16): + +| 口径 | k_l1 | 单核 DMA 命令数 | 总时延 | +|---|---|---|---| +| 理论 IterBatch(k_l1 反推=1024) | 1024 | **16** | 85.0us | +| 源码式承接(k_l1 上限 512B/dt=256,ASW 模拟) | 256 | **64** | 84.5us | + +**T_cmd=0 假设下时延差 <0.6%**——形态 d 的收益几乎全部押在 **T_cmd > 0**(每核命令少 4×) +与 L2 重复读消除上。→ **T_cmd 标定是该批次的入场券**(见 §4.3):若标定出 T_cmd 可观 +(如 ≥100ns),form_d 例命令差 48 次 → ~5us 级收益;若 T_cmd≈0,则本批次降级为 +"框架统一 + 大 M/N case 的 L2 重复读消除"(form_c 型例:ASW 承接的 L2 重读 ~96MB ≈ 18.5us 级, +需实测扣除其流水掩盖)。 + +**修改重点**(若标定结果支持做): +1. host `iterbatch_basicapi_tiling.cpp`:IsCapable 放宽——L1 放不下双 batch 整 K 时进入形态 + 选择(a/c/d),按理论公式算驻留侧/k_l1;DoOpTiling 输出形态字段; +2. kernel:cmct `BlockMmad`(IterBatch) 的 L1 布局与循环次序重写(c 形态:驻留侧一次 CopyIn、 + 对侧 K 分块双缓冲,batch 边界半预算预取;d 形态:两侧 K 分块成对流水)—— + **这是全计划最难的 kernel 改动**(L1 flag 4 组 + L0 乒乓 + L0C 半区 + AIC↔AIV 握手耦合极密); + tilingData `BatchMatMulV3IterBatchBasicTilingData` 加形态/分侧参数字段(pack(8) 对齐, + host/kernel 同步改);尽量纯运行期字段表达以**避免新增模板组合/二进制**; +3. 同步考虑启用 unitflag(细粒度排空)以压低 drain——理论 drain 模型(末 batch T_comp+T_write) + 在 unitflag=0 的源码上可能**低估**真实排空,需实测校准(这也影响理论模型自身的 drain 闭式)。 + +**验证重点**:T_cmd 标定先行;形态 c/d 定向 case(M/N>256 且 2(MK+KN)>L1、以及双侧超 L1)的 +总时延与 L2 流量对比;batch 边界气泡(核内时间线);正确性(K 分段累加顺序变化)。 + +### 2.4 MergeBatch 准入补齐 + 仲裁接线(P2,纯 host) + +**理论方案**(`01_MergeBatch分支.md`;与 bmmv3 对拍器口径的逐项对照另见 +`04_差异对照_bmmv3_vs_BMM_Theory.md` §2):5 条件准入(含 ③ 单核搬移量 ≥480KB、④ 单 tile ≥16KB、 +⑤ AI < R16/b0 访存 Bound 守卫),b0 = min(L0C/L0A/L0B 容量上限, R16 算存比上限, b_core) 取因子; +k_l1 = min(L1 反推, K, 512B/dt);与 IterBatch 重叠区按净收益仲裁 +(命令节省×T_cmd + 搬移效率节省 − drain 惩罚;**L1 绑定(k_l10 时放大 b0 倍——**同样依赖 T_cmd 标定**。 +条件③④⑤ 误捕获区的典型代价:tile=4KB → 有效带宽 ×0.25,或计算 Bound 下 b0 倍冗余 MMAD。 +→ 该批次定位为**健壮性/正确性加固**,收益以上板实测误捕获 case 为准。 + +**验证重点**:构造条件③④⑤ 各自的越界 case(小搬移量、小 tile、高 AI),确认修改后不再进 +MergeBatch 且落点分支时延更优;L1 绑定仲裁区 case(merge_iter_arbitrate 类:B=128, M=N=64, +K=512);已命中 case 全量回归零变化。 + +### 2.5 转Matmul / 特殊分支 / 广播(P4,对齐核查) + +| 理论 | 源码对应 | 核查结论 | +|---|---|---| +| K=0 纯 AIV 写值 | `K_EQUAL_ZERO(0)`(AIV 清输出 kernel) | ✅ 已覆盖,对齐即可 | +| K=1 逐元素乘走 AIV | `TO_MUL(1)`(matmul2mul tiling + vector kernel) | ✅ 已覆盖;理论 B<128 的 AIV 单缓冲退化需核查源码对应行为 | +| BatchB=1 零代价折叠 | `MergeBatchAndMAxis`(batchB==1 且 !isATrans → 折进 M) | ✅ 已覆盖 | +| BatchA=1:A 小留 BMM 广播 / A 大比较重排 | ITER_BATCH_BROADCAST(4)(单广播轴)/ ASW 广播模型 | ⚠️ "A 大则重排转 Matmul"源码无,低优先 | +| 交叉广播(双轴/多轴) | 落 ASW_Basic/BASE | ✅ 与理论一致(理论也由 ASW 承接) | + +### 2.6 路由层差异(贯穿项) + +1. **优先级顺序**:源码 StreamK(2) 先于 MergeBatch(3)/IterBatch(5)。重叠区(B≥C 且 P≤C/2 且 + K≥门槛)源码必选 StreamK,理论先走切 B。模型测算该区域两者接近(切 K 并行度收益 ≈ 切 B 免 + 共享收益),**维持源码顺序不改**,用定向 case 实测确认无显著回退即可。 +2. **仲裁机制**:源码无"时延模型终审"。短期用各分支 IsCapable 的判据细化(M5(a)、S1/S2)逼近 + 理论裁决;长期若要引入端到端时延估计进 tiling,需单独评审(tiling 耗时预算、常量标定维护)。 + +--- + +## 3. 横切差异(时延模型与口径) + +| 项 | 理论模型 | 源码 tiling | 处置 | +|---|---|---|---| +| 算力口径 | Cube-only 13.5T/核(432T/32 核,issue#40) | freq×8K≈13.2T(经验式) | 一致(差 2%),无需改 | +| 带宽口径 | GM 1.6TB/s 读写共享;L2 5.2TB/s 读写独享 | GetHbmBW≈1.6T、GetL2BW≈5.16T | 一致,无需改 | +| 输出落点 | S_A(整 case ≤L2)时写 L2 写口,否则直写 GM | 全部直写 GM,C 从不显式写 L2 | **观察项**:S_A 小区 case 理论上有 GM 写时延节省;硬件 L2 写回自然缓存可能已近似,msProf 实测后再决定是否建模差异 | +| T_cmd(DMA 命令固定开销) | 默认 0(未标定) | 源码无显式建模,但 stepK≤8、dValue 512B 等限制隐含"命令有代价"的工程经验 | **标定项**(§4.3),结果决定 IterBatch/MergeBatch 仲裁类收益是否成立 | +| 搬移效率 | eff=min(1, tile/16KB)(issue#36) | 源码用 16KB/64KB 硬编码阈值(fullCopySize=64KB、mmadCount=8) | 同源不同形,验证 tile 饱和点 | +| drain | 闭式(issue#37) | kernel unitflag=0,tile 级双缓冲排空 | 实测校准理论 drain | +| fp32 大 K | 不建模 | 核内 splitK(8192 阈值串行累加) | 理论补标注即可,不动源码 | + +--- + +## 4. 上板验证方案(Ascend950PR 主 bin / arch35) + +### 4.1 环境与工具 + +- 芯片:Ascend950PR 主 bin(32 AIC / 64 AIV,HBM 1.6TB/s,L2 128MB);arch=DAV_3510。 +- 入口:`aclnnBatchMatMul`(`examples/arch35/test_aclnn_batchmatmul.cpp` 为模板自建 harness), + dtype 以 bf16 为主测面,fp16/fp32 抽查。 +- 测量:**msProf** 算子级时延(总时延 = case 执行完的墙钟)+ 核间时间线(尾轮空转可视化); + 正确性用 `tests/assets/bmmv3_aclnn_golden.py` 对拍(bf16 容差按现有 ST 标准)。 +- 对照:同一 case 跑**修改前源码 build**(基线)与**修改后 build**,各 ≥20 次取中位数; + tiling 日志(OP_LOGI/D)落盘确认实际命中策略与理论预测分支一致。 + +### 4.2 case 集设计(三层) + +1. **定向差异 case**(每批次一张表,见 §2 各节"验证重点"):围绕每个差异点的进入/退出边界构造, + 含边界两侧 ±1 档; +2. **理论 demo 全量**:本仓 `examples/cases_demo.csv` 44 例全跑,与理论 recommend 分支预测比对 + "预测分支 == 实际命中策略"命中率(目标 100%,除已知口径差异清单); +3. **回归面**:源码自带 ST(`tests/st/arch35/ttk_*.csv` + atk json)全量,保证零回退; + 另加理论压力回归同分布随机 case(seed7/6000 量级采样到可编译子集)抽查时延不回退。 + +### 4.3 标定项(先行,阻塞批次 3/4 的裁决) + +| 标定 | 方法 | 用途 | +|---|---|---| +| **T_cmd** | 固定 case,变 k_l1 分段数(命令数)扫 MTE2 时延,线性拟合斜率=带宽、截距/命令数=T_cmd | 决定 IterBatch 形态化与 Merge 仲裁的真实收益(批次 3/4 立项裁决) | +| 归约段落点 | StreamK case 扫 K,拆 reduce 段时延,对比 L2(5.2T)/GM(0.64~1.6T) 两口径模型 | 决定 θ_c' 取值与 workspace 策略(批次 1 内完成) | +| tile 效率曲线 | 变单命令 tile 大小(4/8/16/32KB)测有效带宽 | 验证 eff=min(1,tile/16KB) 模型与 16KB 饱和点(issue#36 口径上板确认) | +| drain 量级 | 单波 case 变 N_blk 测尾轮/排空暴露 | 校准理论 drain 闭式(unitflag=0 下) | +| fp32 Cube 算力 | fp32 大 K 计算 Bound case | 确认 ½ 假设(docs/05 §2 待标定项) | + +### 4.4 通过标准(提 PR 门槛) + +1. 定向差异 case:修改后总时延 **严格更短**(中位数,超过噪声带 ~2%); +2. 回归面:零精度问题、零 crash、时延回退 case 比例 = 0(个别 <2% 且可解释除外); +3. 理论预测分支与实际上板命中策略一致率 100%(不一致项必须有文档化解释); +4. tiling 耗时不显著增长(host 枚举量增加控制在毫秒级)。 + +--- + +## 5. 实施批次与 PR 计划 + +| 批次 | 内容 | 改动文件(源码侧) | 依赖 | 风险 | +|---|---|---|---|---| +| 0 | 标定(§4.3)+ 基线库建立(44 例 + 定向 case 的修改前时延基线) | 无(测试基建) | 板子/harness | 低 | +| 1 | StreamK 准入放宽 + grid_K 推导(§2.1) | `op_host/op_tiling/arch35/batch_matmul_v3_basic_streamk_tiling.cpp`(host-only) | 批次 0 归约口径 | 低(kernel 不动);注意 θ_c 边界 | +| 2 | ASW 方案B 尾轮(host-only)→ 视收益决定是否续作 A1b(kernel 第二套 tile,移植 aswt 范式) | `batch_matmul_v3_asw_basic_tiling.cpp` +(A1b 时)`asw_block_advanced.h` / `asw_kernel_advanced.h` | 批次 0 | 中(方案B 低;A1b 的 index 重映射需细致 review) | +| 3 | MergeBatch 准入补齐 + L1 绑定仲裁(§2.4) | `batch_matmul_v3_mergebatch_basicapi_tiling.cpp`(host-only) | T_cmd 标定 | 低 | +| 4 | IterBatch 形态补全(§2.3),含 unitflag/ drain 校准 | `iterbatch_basicapi_tiling.cpp` + cmct `block_mmad_iterbatch.h` / scheduler + tilingData | T_cmd 标定结果支持 | **高**(kernel 流水重写);可拆子 PR(先 host 形态 d → 再 kernel c/d) | + +每个批次独立 PR:附理论文档链接(本仓 docs/02 对应分支文档 + 本文)、基线/修改后时延对照表、 +ST/UT 通过证据、定向 case 清单。PR 顺序即批次顺序(host-only 先行,kernel 改动殿后)。 + +--- + +## 6. 风险与开放问题 + +1. **T_cmd 若 ≈0**:批次 3 仲裁价值缩水为"防误捕获",批次 4 失去主要收益支撑 → 届时重新裁决 + 是否只做 host 侧准入/路由对齐。 +2. **方案B 的流量放大**(tile 缩 1/√g → 搬入周长和放大)理论标注不入模型(issue#37 P4), + 周长型主导角区可能吞掉尾轮收益——批次 2 必须含 GM/L2 流量实测。 +3. **理论 ASW 降核口径**(P=L0C 满载粒度)与源码 usedCoreNum 口径不同,"理论落点分支预测" + 在降核区需要对齐后再比对。 +4. **Blaze/旧库栈在仓外**:StreamK 的 TENSOR 级与 IterBatch 高级版主体实现不在当前源码包内, + 批次 1/4 若需触及要单独申请对应源码包;优先走仓内可读的 cmct 内置栈。 +5. **理论模型自身的已知简化**(docs/05 §3 R6、issue#37 P3/P4)在上板数据回来后需要一轮 + 模型校准,再反哺后续批次的预期值。 +6. **确定性等级**:StreamK 相关改动保持 deterministic_level>1 禁用不变;批次 1 PR 需带 + level=0/1 的数值稳定性证据。 + +--- + +*版本:v1.0 | 2026-09-07 | 基于 BMM_Theory main(issue#40 Cube-only 口径)与 +ops-nn batch_mat_mul_v3 arch35 源码快照比对;量化数字由 `bmm_theory` 测算脚本产出 +(ASCEND950PR 规格,T_cmd=0 未标定假设),仅供排期参考。*