已关闭
AdaptiveAvgPoo2dGrad性能优化不达标 #3743
小王!创建于  7月1日关闭于  7月2日
小王!
小王!成员
7月1日 创建

优化方案如下
一、SIMT 模板的性能优化:

1、针对 H 方向输出尺寸大于输入尺寸、W 方向输出尺寸较小且输入 W 较宽的场景,新增 SmallOutWSegFast 快路径分支。该分支主要覆盖 hOut > hInwOut 为 2、3、4 的场景,并根据 wIn 设置不同的命中阈值。原通用路径是按每个 gradX[n,c,h,w] 元素逐点反查对应的 gradY 窗口,多个相邻输入 W 位置会重复读取和累加相同或高度相似的 gradY 数据。优化后改为按 row + W segment 组织任务,每个任务处理一个 (n,c,h,segment),先计算该 segment 对应的梯度值,再批量写回连续的输入 W 区间,从而减少重复读 GM、重复计算窗口边界和重复累加的开销。

2、针对 W 方向输出很小但输入 W 较宽的场景,在 SmallOutWSegFast 中将输入 W 维度按照输出窗口覆盖关系拆成多个连续 segment。对于 OUT_W 个输出窗口,最多拆成 2 * OUT_W - 1 个 segment,其中普通 segment 只由一个输出 W 窗口贡献,边界 segment 由相邻两个输出 W 窗口共同贡献。每个 segment 预先记录 startWendWkW0kW1 等信息,计算时无需每个输入 W 位置都重复计算 owStartowEndiw0iw1kW。segment 内的 gradX 值相同或由固定的相邻输出窗口组合得到,因此可以一次计算后批量写回 [startW, endW) 连续区间。

3、针对 H 方向扩张场景,SmallOutWSegFast 利用 adaptive avg pool 的窗口覆盖规律对 H 方向计算进行了简化。在 hOut > hIn 的情况下,大多数输出 H 窗口只覆盖一个输入 H 位置,只有输入 H 的左右边界附近可能出现跨输入窗口的情况。优化路径不再对每个 oh 都反复计算 ih0ih1kH,而是通过 leftCrossrightCross 判断首尾是否跨界:边界位置使用 0.5f 权重处理,中间位置直接累加。这样可以减少大量快除、窗口起止计算和标量除法开销。

4、针对输入 H 为 1 的退化场景,新增 HInOne 专用分支。该场景下输入高度只有一行,所有输出 H 方向的梯度都会累加到同一个输入 H 位置,因此不需要再计算 H 方向的 ohStartohEndih0ih1kH。该分支将计算规模从 n * c * inH * inW 简化为 n * c * inW,只保留 W 方向的窗口反推和所有输出 H 的累加,降低了循环复杂度和重复边界计算开销。

5、针对小 outWwIn 较小的场景,保留并细化了 SmallOutWRow 行级聚合分支。该分支以一整行 (n,c,h) 为任务粒度,先对每个输出 W 聚合 H 方向贡献,得到 owSum[OUT_W],再遍历输入 W,根据每个输入 W 是否落在对应输出窗口覆盖范围内完成写回。对于 wIn 较小的 shape,这种行级聚合方式可以避免任务拆得过细导致调度开销变大,同时复用同一行上的 gradY 读取结果,减少多个输入 W 位置重复读取同一批输出梯度。

6、针对 H 方向极端扩张且 wOut == 2wIn 较小的场景,新增 HExpandW2SmallFast 快路径。当 hOut 远大于 hIn 时,如果仍采用行级聚合,一个线程需要处理很长的 H 方向累加,单线程工作量过大、并行度不足。因此该分支重新按输入元素维度并行,同时针对 wOut == 2 的固定结构进行手写优化:直接根据输入 W 判断当前点只由 ow0 贡献、只由 ow1 贡献,还是由两个输出窗口共同贡献,避免通用路径中反复计算 W 方向窗口边界。H 方向中间部分采用循环展开累加,边界位置使用半权重处理,以降低极端 H 扩张场景下的计算开销。

7、针对固定 H 扩张比例的特殊场景,新增 HExpandExactOutWSmallFast<12> 分支。该分支命中 hIn == 2hOut == 24 的场景,此时每个输入 H 精确对应 12 个输出 H。代码中直接使用固定的 H_SCALE = 12 进行展开累加,省去了通用路径中对 ohStartohEndih0ih1kH 的动态计算。该优化属于特定 shape 的定制快路径,适合固定比例扩张场景下提升性能。

8、针对 H 方向输入尺寸大于输出尺寸、W 方向输出尺寸大幅大于输入尺寸的场景,新增 HReduceWExpandFast 分支。该分支覆盖 hIn > hOutwOut >= wIn * 4 的情况。此类场景下,一个输入 W 位置可能被多个输出 W 窗口覆盖,通用路径会对每个 ow 都计算 iw0iw1kW。优化后将 W 方向覆盖区间拆成首、中、尾三部分:首尾位置保留真实 kW 计算,中间大部分窗口通常只覆盖一个输入 W 位置,可以直接累加,从而减少 W 方向大量重复的窗口边界计算和除法操作。

9、在通用路径和各类快路径中还做了细粒度标量优化。首先,将 N 和 C 两个维度合并为 nc 进行索引计算,避免在热路径中额外拆分 nc;其次,提前计算 base = nc * outHW,减少内层循环中的重复乘法;再次,将部分除法改为预先计算倒数后使用乘法,例如 invKHinvKW;最后,在 segment 批量写回时,先将浮点梯度转换为 VALUE_T,再写回连续 W 区间,避免同一个梯度值重复进行类型转换。这些优化不改变原有计算语义,但可以降低 SIMT 热路径中的标量计算、快除和类型转换开销。

10、对于未命中特殊 shape 的场景,保留优化后的通用 Nchw fallback 路径,保证功能覆盖完整。通用路径仍然按照每个 gradX 元素反查对应的输出窗口并累加 gradY / (kH * kW),但相比原始实现,已经合并了 n/c 索引、提前计算 outHWbase,并在 H 方向提前计算 invKH,因此即使不走特殊快路径,也能减少部分重复计算。
二、small kernel 模板的性能优化:

1、针对极端 resize、小 W、大比例 H/W 扩张或压缩的场景,新增 small kernel 规避逻辑。此类 shape 更适合 SIMT 快路径处理,small kernel 不再强行命中,避免因 UB 转置、窗口反推和重复累加带来额外开销。

2、针对原 tiling 只满足 UB 和核数即可返回的问题,新增代价模型搜索。优化后会遍历 highAxisInnerhOutputInnerwOutputInner,综合评估 buffer 开销、block 数、core 利用率、highAxis padding 和尾块 VL 利用率,选择更优切分。

3、针对 H/W 切分回退策略,新增严格收缩的 ShrinkInnerStrict 逻辑。相比原来通过增加 outer 间接调整 inner,新逻辑直接保证 inner 逐步变小,避免切分停滞,使 UB 占用和核数并行度更容易同时满足。

4、针对计算阶段 H 方向仍走标量反推的问题,新增 H 方向窗口信息向量化预计算。优化后 H/W 两个方向都批量计算 start/end/cover,并缓存到 UB 临时 buffer,减少内层循环中的整数除法、边界 clamp 和函数调用开销。

5、针对 highAxis 尾块不规整和重复除法问题,新增 highAxisLocalStride_ 对齐本地高轴,并预计算 invCoverW。计算时用 invCoverH * invCoverW 得到 scale,减少逐点浮点除法,同时让转置、cast 和 MicroAPI 累加访问更规整。

likedislike
小王!
小王!成员
7月1日 评论:

/assign

likedislike
CANN-robotCANN-robot成员
7月1日 将 qq_52056150 设为负责人
yuning_chen
yuning_chen成员
7月1日 评论:

/assign @qq_52056150

likedislike
CANN-robot
CANN-robot成员
7月1日 评论:

Notice

This issue is already assigned to qq_52056150. Please do not assign repeatedly.

likedislike
小王!小王!成员
7月1日 修改标题为 “AdaptiveAvgPoo2dGrad性能优化不达标”,原标题为“AdaptiveAvgPoo2dGrad性能优化”
小王!小王!成员
7月1日 修改了issue 的描述
CANN-robotCANN-robot成员
7月2日 关闭了 issue
CANN-robotCANN-robot成员
7月2日 添加了label:resolved