03 · 流水线台账(msprof on 310P:三层视角 + 实测管线占比 + 工具限制清单)
结论先行
- Cube 化之后的真瓶颈是 Scalar 管,不是 Cube:shape
1×16×128×128×128的单 kernel 里 Scalar 651.7µs / ratio 0.674,而 Cube(mac) 只有 12.6µs / 0.013(1.3%)(docs/PR-1135-d0906c3e/11-流水线剖析msprof实战.md §1.3)。继续优化的方向在标量循环批量化,不在 Cube。 - Cube + MTE1 合计 <2.5%(实测 22.7µs = 2.38%,本报告计算)印证"310P 缺 Fixpipe → L0A/L0B 装载与 Mmad 被 GM staging 往返支配"——即 UB→GM→L1 的绕行代价(同文 §1.3 结论 2,机理见
docs/PR-1135-d0906c3e/00 §1第 1 条"必须手工走 L0C→UB 的 NZ 转换")。 - 8 核并行是良好的:单 kernel 953~967µs,同 shape 端到端 1.151ms → 器件忙时占壁钟 83.0%(本报告计算)。docs 原文用"×3 次调用 ≈ 2.9ms vs 1.15ms"表述(§1.3 结论 3),本台账两种口径并列,并指出前者的量纲混用(§4.3)。
- msprof 在 310P 上有 9 条工具限制(§6),其中两条直接决定采集方案:
msprof op带--kernel-name匹配自定义算子必崩 ERR99999(复现 3 次);--output的父目录链不能有 group/other 写权限。因此绝对延迟一律走 pytest,msprof 只用于占比分析(§6 第 9 条)。 - 唯一能直接检验"泛化重构是否改了标量侧工作量"的实验(a9c66ddb vs d0906c3e 的 scalar_ratio 对比)本次未做(§7)。
1. 三层视角:看什么、用什么产物
| 视角 | 能看到什么 | 工具 / 产物 | 本台账的实测状态 |
|---|---|---|---|
| L1 分管线耗时占比 | kernel 内部 S / V / M / MTE1 / MTE2 / MTE3 各管占用时间与 ratio | msprof → op_summary_*.csv;深挖要到 device_0/sqlite/ai_core_metrics 表 | 已实测(§3) |
| L2 任务时序 | 每次内核启动的起止时刻、等待时间、前后算子顺序 | task_time_*.csv + hwts.db | 已实测:CGDR 三次启动 Waiting 均为 0 附近(§5.1) |
| L3 全链路 timeline | AscendCL API → Runtime → 设备任务的逐事件时间轴(可视化) | msprof_*.json(Chrome trace 兼容,本例 128KB,导入 Perfetto UI / MindStudio Insight) | 已采到,事件三类已确认(§5.2) |
出处:docs/PR-1135-d0906c3e/11-流水线剖析msprof实战.md §0 表 L7-15、§1.4 L100-104、§1.5 L106-110。
2. 采集命令与产物路径
被测 shape:B,H,T,DK,DV = 1,16,128,128,128,注释口径是"代表 shape:Cube 化收益最大的那个";驱动脚本 /data/lingchen/cgdr_lab/prof_smoke/run_one.py 只跑算子、无 pytest 噪音,循环 3 次 + torch.npu.synchronize()(…/11-流水线剖析msprof实战.md §1.1 L19-41)。
source /usr/local/Ascend/ascend-toolkit/set_env.sh
export PYTHONPATH=$PYTHONPATH:/data/lingchen/cgdr_lab/shim \
LITE_BOOST_OPS_LIB=/data/lingchen/mindspore-lite/mindspore-lite/lite_boost/build/liblite_boost_ops.so \
ASCEND_CUSTOM_OPP_PATH=/data/lingchen/cgdr_lab/builds/d0906c3e/ascend310p/mslite_custom_ops
msprof --application="python3 /data/lingchen/cgdr_lab/prof_smoke/run_one.py" \
--output=/data/lingchen/cgdr_lab/prof_smoke/out \
--aic-metrics=PipeUtilization --task-time=on- 实测采集 + 解析约 60~70 秒;产物在
out/PROF_<时间戳>_<随机串>/mindstudio_profiler_output/:op_summary / op_statistic / task_time / api_statistic四张 CSV +msprof_*.jsontimeline +device_0/sqlite/*.db原始库(§1.2 L56-59)。 - L1 读数不走 CSV:CGDR 的分管线数据要从
device_0/sqlite/ai_core_metricsJOINge_summary(op_name LIKE 'ChunkGated%')取,且必须先把 PROF 目录copytree到/tmp才能打开 sqlite(§1.3 L67-79)。 - 权限前置:
chmod go-w /data/lingchen/cgdr_lab/prof_smoke(§2 L118)。
3. L1 实测:CGDR kernel 的分管线占比
被测构建 d0906c3e,shape S2 = 1×16×128×128×128,单 kernel ~955µs,AICore 8 核(docs/PR-1135-d0906c3e/11 §1.3 L81-90):
| 管线 | time (µs) | ratio(docs 原值) | docs 解读 | 本报告计算:µs ÷ 955 | ratio 反推分母 µs |
|---|---|---|---|---|---|
| Scalar | 651.7 | 0.674 | 最大头:标量循环(块分解调度、Addr 计算、SetValue) | 0.6824 | 966.9 |
| Vector | 295.4 | 0.306 | 高维 Mul / Cast / NZ→ND 搬运 | 0.3093 | 965.4 |
| MTE2 | 125.9 | 0.131 | GM→UB 输入装载 | 0.1318 | 961.1 |
| MTE3 | 49.2 | 0.051 | UB→GM 写回 | 0.0515 | 964.7 |
| Cube (mac) | 12.6 | 0.013 | 裸 Mmad 五件套的全部 Cube 计算 | 0.0132 | 969.2 |
| MTE1 | 10.1 | 0.010 | L1→L0 装载 | 0.0106 | 1010.0(ratio 只给 2 位有效) |
一致性自检(本报告计算):
- 六行 ratio 反推出的分母落在 961~969µs,与同文 §1.3 结论 3 写的观测窗口"953~967 us"重合 → ratio 与 µs 两列互相对得上,955µs 是该窗口内的一个代表值,表内数据自洽。
- 六行 µs 求和 = 1144.9µs、ratio 求和 = 1.185 > 1 → 这六个数是各管各自的忙占比,会相互重叠,不是把壁钟切成六块。因此"Scalar 67%"的正确读法是"标量管忙了单核时间的 67%",不能读成"67% 的端到端时间花在标量"。
- Scalar + Vector = 947.1µs = 99.17% 的 955µs;Cube + MTE1 = 22.7µs = 2.38%(ratio 相加 0.013+0.010=0.023 同结论)。
- Vector / Scalar = 0.4533 → 标量管的工作量是向量管的 2.2 倍,这是"Cube 化把工作量转移到调度/标量侧"的量化形态。
4. 三条可讲结论
4.1 "Cube 化后的 kernel 其实是 Scalar 瓶颈"(67%)
原始形态:六处 Cube 函数省下的 Vector 工作量转移到了调度/标量侧(块分解调度、Addr 计算、SetValue),Cube 本身几乎空闲(1.3%)。
本报告补的算术:Scalar 651.7µs 比 Vector + MTE2 + MTE3 之和(470.5µs)还多 38.5%,所以"下一个该优化的对象"排序是 Scalar > Vector > MTE2,而不是 Cube。
4.2 Cube + MTE1 <2.5% = 缺 Fixpipe 的 GM 绕行代价
出处:docs/PR-1135-d0906c3e/11 §1.3 结论 2("L0A/L0B 装载与 Mmad 都被 GM staging 往返支配(UB→GM→L1 绕行,见 PR-1135/01 §2)")。机理锚点(本仓库可核对的代码):
src/d0906c3e/op_kernel/chunk_gated_delta_rule.h:249-255GetCubeStageBase(uint32_t slot):Cube 输入先经 workspace 的每 core 双 slot GM 暂存,再从 GM 当GlobalTensor进 L1;对应 docs 表述见docs/PR-1135-d0906c3e/10-Commit演进史.md §1.1 L75-77("A/B 借 GM 中转:UB 上的 FP32 数据 Cast 成 FP16 后先 DataCopy 出 GM,再从 GM 当 GlobalTensor Nd2Nz 进 L1")。- workspace 预算里的直接体现:
kRawMatmulStageBytesPerCore = kCubeStageSlotCount × (2×64×128 + 128×128) × 2B(src/d0906c3e/op_host/chunk_gated_delta_rule_tiling.cpp:48-49,docs 记为"每 core 预留 128KB",docs/PR-1135-d0906c3e/10 §1.1 L33-34)。 - 量级判断(本报告计算):Cube 12.6µs + MTE1 10.1µs = 22.7µs,而 MTE2 125.9µs(进 GM/从 GM)比整个矩阵乘链路高一个数量级 → 绕行成本确实记在 MTE 管上而不是 Cube 管上,与"Cube 单元只忙 1.3%"互洽。
4.3 多核并行度:两种口径并列
- docs 原文(§1.3 结论 3):"单 kernel 953~967 us × 3 次调用 ≈ 2.9ms,而 perf 实测端到端 1.15ms——说明多核并行良好(8 AICore 各算一份,端到端 ≈ 单核时间),数据在 torch_npu 路径上无额外放大。"
- 本报告计算:953/955/967µs × 3 = 2859 / 2865 / 2901µs;2.865ms ÷ 1.151ms = 2.489 倍。
- 量纲提示(本报告):×3 是"3 次调用的器件忙时总和",而 1.151ms 是单次调用的端到端延迟,两者相除没有直接的物理意义。等价且更干净的算法是把单次调用对齐:单 kernel 955µs vs 单次端到端 1151µs → 83.0%,即一次调用的壁钟几乎全部被 kernel 执行占据(余量 196µs = 17% 是 host 侧 aclnn/入队开销),没有出现"8 核串行 = 8×单核时间"的形态。这支持 docs 的结论,但不支持它的具体算式,两处并列记录。
- 支撑"满核"的代码事实(本报告读代码,非实测):工作单元数 =
B × hv × vTileCount,blockDim = min(工作单元数, aivNum)(src/d0906c3e/op_host/chunk_gated_delta_rule_tiling.cpp:315-322,aivNum = platform.GetCoreNumAiv()见同文:86);S2 的 B=1、hv=16、dv=128 → vTileCount=1 → 16 ≥ 8 核 → blockDim=8。
5. L2 / L3 读数(实测状态)
| 层 | 实测内容 | 出处 |
|---|---|---|
L2 task_time_*.csv | 每行一次任务,Waiting 列 = 任务排队等流/等依赖的时间;CGDR 三次启动 Waiting 均在 0 附近——驱动是同步循环,没有流水放大。docs 明示:若在真实 decode 服务里测,这列能暴露 host 供数瓶颈 | docs/PR-1135-d0906c3e/11 §1.4 L100-104 |
L3 msprof_*.json | Chrome trace 兼容,本例 128KB;事件三类:AscendCL@aclnnChunkGatedDeltaRule(Tiling / GetWork) → runtime → 设备任务;可直接拖进 Perfetto UI 或用 MindStudio Insight | docs/PR-1135-d0906c3e/11 §1.5 L106-110 |
6. msprof 在 310P 上的工具限制清单(9 条,逐条带出处)
| # | 限制 | 症状 / 对策 | 出处 |
|---|---|---|---|
| 1 | msprof op --application=…(不带 --kernel-name) | 默认只抓驱动里的第一个 kernel(本例是 torch 的 Transpose,不是 CGDR)→ 结果不可用 | §2 L123-125 |
| 2 | msprof op --kernel-name=ChunkGatedDeltaRule | 程序崩溃 ERR99999 application exception,复现 3 次——自定义算子名匹配在 torch_npu 路径上不可用 | §2 L126-127 |
| 3 | msprof op --launch-count / --warm-up | 同样触发崩溃 | §2 L128 |
| 4 | --output 的父目录链有 group/other 写权限 | 报 "output parent dir permission wrong";chmod go-w <dir> 解决(msprof op 子命令强校验,主命令偶尔也查) | §1.2 L61-63、§2 L118 |
| 5 | --reports=op_summary,… 语法 | 本版本不支持(报 does not exist)→ 保持默认 | §4 第 2 条 L151 |
| 6 | metrics 组合用逗号(PipeUtilization,MemoryL0) | 主命令路径报 invalid,310P 版本一次只能指定一组 | §4 第 3 条 L152 |
| 7 | ResourceConflictRatio / MemoryL0 等指标 | 采集成功、原始数据落 device_0/data/aicore.data.*,但解析器在 310P 上不生成 op_summary_*.csv;数据只在 sqlite ai_core_metrics 的 bank/resc 冲突列(Transpose 亲测全 0,CGDR 未捕获到)。替代方案:看同一次采集里的 mte1_ratio 异常升高 + 已捕获的硬件报错串 L0C read/write conflict | §4 第 1 条 L144-150 |
| 8 | PROF 目录内直接开 sqlite | unable to open(目录权限/锁)→ 先 cp -r 到 /tmp 再读 | §4 第 4 条 L154、§5 L169 |
| 9 | Profiling 期间性能略降(采集开销) | 绝对延迟一律用 pytest perf 路径,msprof 数据只做占比分析 | §4 第 5 条 L155-156 |
由 1~3 条得出的可用路径(docs 结论):msprof op 的 8 张指标表只对"驱动里只有一个 kernel"的场景可靠(纯 ACL C 程序直接调单算子);torch_npu 混合调用场景一律用 §1 的主命令路径(msprof --application=… --aic-metrics=PipeUtilization --task-time=on)。出处:§2 L130-131。