v1.3: 同步HTML

This commit is contained in:
2026-08-27 08:47:39 +00:00
parent 1e92d348df
commit 5a017ade98

View File

@@ -190,23 +190,36 @@ $$</div>
<tr><td>UnitFlag 单缓冲</td><td>256×25665536 元素)</td><td></td><td>16×16×16 粒度)</td><td>max($T_{comp}$, $T_{write}$)</td></tr></table>
<p>两种方案的稳态时延相同(都是 max($T_{comp}$, $T_{write}$)),但 UnitFlag 单缓冲的 tile 更大 → 总 tile 数更少 → 循环开销更小。<b>但当前 BMM ASW kernel 未启用 UnitFlag</b><code>unitFlag = 0</code>,注释 "each l0 only process one block, disable unit flag"),且源码在 baseM=baseN=256 时已自动选 dbL0C=1256×256×4B×2 &gt; L0C——即<b>源码已经是单缓冲 + 无 UnitFlag</b>tile 到顶但无流水交叠。</p>
<p>*建议*:对计算 Bound 的 case 启用 UnitFlagMMAD 与 Fixpipe 流水并行),可将单 tile 时延从 $T_{comp} + T_{write}$ 降至 $\max(T_{comp}, T_{write})$。对访存 Bound 的 caseMTE2 BoundUnitFlag 收益小([CANN 文档](https://www.hiascend.com/document/detail/zh/CANNCommunityEdition/920beta1/API/ascendcopapi/atlasascendc_api_07_0003.html)MTE2 Bound 时 MMAD/FIX 流水可被搬移掩盖)。</p>
<p>BaseM/BaseN 的长宽比跟随 SingleCoreM/SingleCoreN进而跟随 M/N对齐 16 的倍数。<b>长宽比跟随的原因</b></p>
<ol class="tight">
<li><b>L0 tile 均匀密铺</b>SingleCore tile $[\text{singleCoreM}, \text{singleCoreN}]$ 由若干 $[\text{BaseM}, \text{BaseN}]$ L0 tile 密铺而成。若长宽比匹配($\text{BaseM}/\text{BaseN} \approx \text{singleCoreM}/\text{singleCoreN}$),则 $stepM = \text{singleCoreM}/\text{BaseM}$ 和 $stepN = \text{singleCoreN}/\text{BaseN}$ 接近相等L0 tile 在两个维度上的切分次数均匀,边缘碎块最少;</li>
<li><b>L1→L0 搬移效率匹配</b>L0A 搬移 $[\text{BaseM}, baseK]$、L0B 搬移 $[baseK, \text{BaseN}]$。长宽比匹配时L0A 和 L0B 的搬移量接近($\text{BaseM} \cdot baseK \approx baseK \cdot \text{BaseN}$两条搬移通路负载均衡Cube 不会因等某一侧数据而空转;</li>
<li><b>L0C 写出效率</b>Fixpipe 从 L0C 写出 $[\text{BaseM}, \text{BaseN}]$ 的结果到 GM。长宽比匹配时写出块的连续维N 向)长度与 GM 中 C 矩阵的行 stride 匹配,写出效率最高。</li>
</ol>
<p>若长宽比严重不匹配(如 M ≫ N 但 BaseM = BaseN则 M 向切分次数远多于 N 向L0A 搬移频繁而 L0B 闲置——Cube 等待 L0A 数据流水线利用率下降。baseK 由 L0A/L0B 容量决定L1→L0 搬移无 dValue 要求dValue 约束的是 GM→L1 的 $k_{L1}$</p>
<p>BaseM/BaseN 的长宽比<b>应尽量方形</b>(而非跟随 M/N对齐 16 的倍数。<b>推导</b></p>
<p><b>1. GM→L1 搬移与 BaseM/N 无关</b>GM→L1 搬移的是 $[\text{singleCoreM}, k_{L1}]$A和 $[k_{L1}, \text{singleCoreN}]$B其 dValue 由 $k_{L1}$A和 $\text{singleCoreN}$B决定——BaseM/N 的长宽比不参与 GM→L1 搬移参数。<b>长宽比跟随 M/N 不会改善 GM→L1 效率。</b></p>
<p><b>2. L0A = L0B = 64KB 等容量 → 方形 tile 用满两侧</b>L0A 装 $\text{BaseM} \times baseK$L0B 装 $baseK \times \text{BaseN}$。若长宽比跟随 M/N如 M/N = 4BaseM=512、BaseN=128</p>
<div class="math">$$
baseK = \min\Big(\frac{L0A}{2 \cdot \text{BaseM} \cdot dtype},\; \frac{L0B}{2 \cdot \text{BaseN} \cdot dtype}\Big) = \min(32,\; 128) = 32
$$</div>
<p>L0A 装满512×32×2×2 = 64KB<b>L0B 只用了 25%</b>32×128×2×2 = 16KB——一半 L0 容量闲置。</p>
<p>方形 tileBaseM=BaseN=256</p>
<div class="math">$$
baseK = \min\Big(\frac{64\text{KB}}{2 \cdot 256 \cdot 2\text{B}},\; \frac{64\text{KB}}{2 \cdot 256 \cdot 2\text{B}}\Big) = 64
$$</div>
<p>L0A 和 L0B <b>同时装满</b>,且 baseK = 64 是长宽比跟随方案baseK=32<b>2 倍</b>——K 维迭代次数减半L1→L0 搬移MTE1单次搬移量翻倍Cube 流水线切换开销减半。</p>
<p><b>3. 方形 tile 是 L0C 面积约束下的最优</b>L0C 约束 $\text{BaseM} \times \text{BaseN} \le 65536$ 只限制面积。在面积固定下,方形使 $\min(\text{BaseM}, \text{BaseN})$ 最大——baseK 的上限由 $\min(\text{BaseM}, \text{BaseN})$ 决定(公式见上),所以方形最大化 baseK。</p>
<p><b>4. 例外</b>:当 M 或 N 小于方形边长时tile 被迫非方形:</p>
<div class="math">$$
\text{BaseM} = \min(\lfloor\sqrt{65536}\rfloor_{16},\; M),\qquad \text{BaseN} = \min\Big(\frac{65536}{\text{BaseM}},\; N\Big) \text{ 向下 16 对齐}
$$</div>
<p>M=128、N=4096 → BaseM=128M 限制、BaseN=512L0C 面积限制)——此时长宽比跟随 M/N 是<b>被迫的</b>M 太小),而非主动选择。</p>
<p><b>结论</b>BaseM/N 长宽比跟随 M/N 的切分方法<b>站不住脚</b>——它使 L0A/L0B 容量利用率失衡一侧闲置、baseK 减半K 迭代翻倍)、且对 GM→L1 搬移无任何收益。正确做法是<b>方形 tile 优先</b>,仅当 M 或 N 小于方形边长时被迫跟随。</p>
<p>baseK 由 L0A/L0B 容量决定L1→L0 搬移无 dValue 要求dValue 约束的是 GM→L1 的 $k_{L1}$</p>
<div class="math">$$
baseK = \min\Big(\frac{L0A}{2 \cdot \text{BaseM} \cdot \text{dtype}},\; \frac{L0B}{2 \cdot \text{BaseN} \cdot \text{dtype}}\Big) \text{ 向下 16 对齐}
$$</div>
<p>核间不切 K 时 K 维度层次关系:$K = \text{singleCoreK} \ge k_{L1} \ge baseK$——$k_{L1}$ 是 GM→L1 的 K 向粒度(须 $k_{L1} \cdot \text{dtype} \ge 256\text{B}$baseK 是 L1→L0 的 K 向粒度(仅受 L0A/L0B 容量约束)。</p>
<p>*BaseM/N 的具体确定过程*host 端枚举16 对齐遍历):</p>
<ol class="tight">
<li>从 BaseM = BaseN = $\lfloor\sqrt{L0C/4\text{B}}\rfloor_{16} = 256$ 开始(方形L0C 单缓冲上限)</li>
<li>检查 baseK = $\min(L0A/(2 \cdot 256 \cdot dtype),\; L0B/(2 \cdot 256 \cdot dtype))$ ≥ 128B/dtype最小高效粒度</li>
<li>baseK 不足,按比例缩小 BaseM/BaseN保持长宽比 ≈ M/N直到 baseK 满足</li>
<li>若 M ≪ N或反之长宽比跟随 M/NBaseM/BaseN ≈ M/N面积保持 65536</li>
<li>从 BaseM = BaseN = $\lfloor\sqrt{L0C/4\text{B}}\rfloor_{16} = 256$ 开始方形L0C 单缓冲上限L0A/L0B 同时满载</li>
<li>检查 baseK = $\min(L0A/(2 \cdot 256 \cdot dtype),\; L0B/(2 \cdot 256 \cdot dtype))$ ≥ 128B/dtype最小高效粒度;不足时按比例缩小 BaseM/BaseN保持方形直到 baseK 满足</li>
<li>M &lt; 256或 N &lt; 256BaseM = $\lfloor M \rfloor_{16}$(或 BaseN = $\lfloor N \rfloor_{16}$),另一维取 $\min(65536/\text{BaseM},\; N)$(或对称)向下 16 对齐——此时 tile 被迫跟随 M/N但这是 M 太小的结果,不是主动选择</li>
<li>方形 tile 的 L0C 面积利用率:$256 \times 256 / 65536 = 100\%$;被迫非方形时面积利用率 = $\text{BaseM} \times \text{BaseN} / 65536$M 或 N 小时必然 &lt; 100%,不可优化)</li>
</ol>
<p>*与源码的差异*:源码默认 baseM=baseN=256硬编码 "256 is better base"),再由 cubeBound 模型L2 供数能力 + 溢出惩罚 + K 向复用)枚举收缩。理论直接从 L0C 容量出发cubeBound 的三项修正可从第一性原理推导①L2 供数速率 vs Cube 耗数速率 → 访存 Bound 时应缩 tile②工作集超 L2 → 增大 tile 减少重复读③K 越大越偏 compute bound → 可放大 tile。两者方向一致源码多了实测调优的余量CUBE_BOUND_RATIO=0.85)。</p>
<h3>5.2 SingleCoreM / SingleCoreN 的确定(每核输出 tile≥ BaseM/N</h3>
@@ -243,7 +256,7 @@ $$</div>
\underbrace{\text{singleCoreM} \cdot k_{L1} \cdot \text{dtype} \ge min\_TileSize}_{\text{A 单次搬移量}},\qquad \underbrace{k_{L1} \cdot \text{singleCoreN} \cdot \text{dtype} \ge min\_TileSize}_{\text{B 单次搬移量}}
$$</div>
<p><b>约束 4——SingleCoreM/N 是 BaseM/N 的整数倍</b>(工程实现要求,保证 L0 tile 边界对齐)。</p>
<p>*选取策略*:在满足约束 1 的前提下SingleCoreM/N 尽量大(搬移效率和 L2 复用最大化)。长宽比跟随 M/N$\text{singleCoreM}/\text{singleCoreN} \approx M/N$对齐到 BaseM/BaseN 的整数倍。</p>
<p>*选取策略*:在满足约束 1 的前提下SingleCoreM/N 尽量大(搬移效率和 L2 复用最大化)。<b>SingleCoreM/N 的长宽比跟随 M/N</b>$\text{singleCoreM}/\text{singleCoreN} \approx M/N$——这与 BaseM/N 的方形策略不同SingleCoreM/N 决定 GM→L1 搬移的 nValue/dValue 参数A 的 nValue=singleCoreMB 的 dValue=singleCoreN跟随 M/N 使两侧搬移量均衡、避免一侧搬移过大成为 GM 带宽瓶颈。对齐到 BaseM/BaseN 的整数倍。</p>
<p>*SingleCoreM/N 的具体确定过程*host 端枚举,与尾轮处理联动):</p>
<ol class="tight">
<li>从约束 1 得到最小块数:$mnCnt_{min} = \lceil C/B \rceil$</li>