ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Perfetto GPU 计算内核 Speed of Light 分析:NVIDIA 计数器抽取与 Compute/Memory/Latency 瓶颈判定

Perfetto GPU 计算内核 Speed of Light 分析:NVIDIA 计数器抽取与 Compute/Memory/Latency 瓶颈判定 Perfetto GPU 计算内核 Speed of Light 分析NVIDIA 计数器抽取与 Compute/Memory/Latency 瓶颈判定【免费下载链接】perfettoProduction-grade client-side tracing, profiling, and analysis for complex software systems.项目地址: https://gitcode.com/GitHub_Trending/pe/perfetto本文基于 Perfetto 的 AI Agent 技能agent skill中 GPU 计算内核分析工作流的 NVIDIA 分支文档 nvidia/speed_of_light.md讲解Speed of Light光速上限这一分析方法如何在已加载的 trace 上运行配套的抽取 SQL得到每个 compute kernel 的计算/内存/L1/L2/DRAM 吞吐百分比与周期计数并据此判定内核是 compute-bound、memory-bound 还是 latency/occupancy-bound。读完后你将掌握 GPU 内核瓶颈分类的完整判定流程、每个输出列与 NVIDIA 硬件计数器的对应关系以及背后 SQL 的实现细节与适用前提。1. Speed of Light 是什么以及它在内核分析中的位置Perfetto 的 agent 技能内置了一套 GPU compute kernel 分析工作流入口文档为 kernel_analysis.md。其出发点很直接一个设备级的GPU 利用率 %无法回答哪个 kernel 是瓶颈、瓶颈在哪种资源上必须做逐 kernel 的分解。该工作流把每个 compute kernel 拆成四个观察面Speed of Light—— 计算/内存/延迟三类瓶颈的分类本文主题Occupancy—— 启动配置与资源压力是否限制了占用率Compute Workload Analysis—— compute-bound 时哪条执行流水线pipe饱和Launch Statistics—— 原始启动配置是否合理。其中 Speed of Light 是第一判定层它比较内核运行到硬件两个天花板——compute计算单元的算术吞吐与memory内存系统吞吐——的距离二者相对高低即给出 bound 类型并指向后续该走的分支。通用解释层文档是 speed_of_light.md具体计数器则因厂商而异当前 trace 中只有 NVIDIA 提供了完整的 Speed of Light 计数器集因此本文聚焦 nvidia/speed_of_light.md 这个 NVIDIA 分支。适用前提trace 已加载进trace_processor会话技能默认用server unixquery --remote保持热会话见 ai/skills/README.md 中warm sessions are the single biggest efficiency win的说明trace 中存在 compute dispatch即gpu_slice表中render_stage_category 20OTHER, 1GRAPHICS, 2COMPUTE且dur 0的 slice。如果先用 vendor 中立的 triage 脚本 kernels_summary.sql 查不到任何行说明该 trace 没有 compute 工作整个工作流不适用trace 记录了 GPU 硬件计数器。GPU 计数器数据源的背景见 docs/data-sources/gpu.md。Phase 1先做全量 triage选出值得深挖的 kernelSpeed of Light 之前工作流要求先跑 vendor 中立的全 kernel 表它只用无论什么 GPU 厂商都存在的数据slice 时序与启动参数目的是点名热点trace_processor query --remote SESSION --query-file $SKILL_ROOT/workflows/gpu/compute/scripts/kernels_summary.sql输出列id启动顺序1 第一个启动的 kernel同一次运行内稳定、kerneldemangled 名称回退到 mangled/slice 名、ugpuhost 唯一 GPU id、dur_ns、block_size、grid_size、registers。选出dur_ns占主导的 kernel或重复出现的高耗时名字记下它的id——后续所有深挖脚本对同一个 kernel 都报同样的id可以跨表对齐。同时按 gpu_info.md 确认该ugpu的厂商与架构决定走哪个 vendor 分支本文是 NVIDIA。2. 运行 NVIDIA Speed of Light 抽取NVIDIA 分支的执行方式只有一条命令trace_processor query --remote SESSION --query-file $SKILL_ROOT/workflows/gpu/compute/nvidia/scripts/speed_of_light.sql几个需要说明的细节--remote ADDR对热会话执行查询而不是每次重新加载本地 trace该参数定义见 docs/reference/trace-processor-cli.md-f, --query-file FILE从文件读取 SQL传-则从 stdin 读取$SKILL_ROOT是技能安装根目录存放SKILL.md的目录。因为技能从插件目录加载、不在用户工作区里相对路径会解析到错误位置所以技能内所有路径统一写成$SKILL_ROOT/path路由器要求 agent 先设置一次该变量。在仓库源码树中它对应ai/skills/perfetto/目录。脚本无参数、作用于整条 trace每个 compute kernel 输出一行按耗时降序最长在前。3. 结果列解读显示标签 → 输出列 → NVIDIA 计数器输出列与 NVIDIA 硬件计数器的完整映射如下继承自 nvidia/speed_of_light.md 的对照表显示标签通用名输出列NVIDIA 计数器Compute Throughputcompute_pctsm__throughput.avg.pct_of_peak_sustained_elapsedMemory Throughputmemory_pctgpu__compute_memory_throughput.avg.pct_of_peak_sustained_elapsedL1 Cache Throughputl1_pctl1tex__throughput.avg.pct_of_peak_sustained_activeL2 Cache Throughputl2_pctlts__throughput.avg.pct_of_peak_sustained_elapsedDRAM Throughputdram_pctgpu__dram_throughput.avg.pct_of_peak_sustained_elapsedElapsed Cycleselapsed_cyclesgpc__cycles_elapsed.maxActive Cyclesactive_cyclessm__cycles_active.avgDurationdur_nsgpu__time_duration.sum缺失时回退为 slice 的 dur在 NVIDIA 上计算单元是SMStreaming Multiprocessor。必须强调一个易错点所有吞吐列都是 **% of peak达到峰值的百分比即该层级有多饱和**而不是缓存命中率。由此dram_pct高 → 真正的 DRAM 带宽瓶颈DRAM-bandwidth boundl1_pct/l2_pct高而dram_pct低 → 工作集主要由缓存供给、而非 DRAM杠杆在数据复用/工作集大小而不是缓存没用上。4. SQL 实现细节从 gpu_slice 到八列透视speed_of_light.sql 共三段完整逻辑如下。第一段_kernels临时表——圈出所有 compute kernel 及其窗口。CREATE PERFETTO TABLE _kernels AS SELECT s.id, s.ts, s.dur, s.arg_set_id, ROW_NUMBER() OVER (ORDER BY s.ts) AS launch_id, EXTRACT_ARG(t.dimension_arg_set_id, ugpu) AS ugpu, COALESCE( EXTRACT_ARG(s.arg_set_id, kernel_demangled_name), EXTRACT_ARG(s.arg_set_id, kernel_name), s.name ) AS kernel FROM gpu_slice AS s JOIN gpu_track AS t ON s.track_id t.id WHERE s.render_stage_category 2 AND s.dur 0;要点render_stage_category 2是 COMPUTE 分类与 triage 脚本同一过滤条件保证各脚本的launch_id对齐ugpu来自 track 维度参数用于后面把计数器钉到正确的 GPU 上kernel 名优先取 demangled回退 mangled再回退 slice 名。第二段_kernel_counters——按 kernel 窗口聚合 COMPUTE 计数器组。CREATE PERFETTO TABLE _kernel_counters AS SELECT k.id AS kernel_id, ct.name AS counter_name, SUM(c.value) AS sum_v, AVG(c.value) AS avg_v FROM _kernels AS k JOIN gpu_counter_group AS g ON g.group_id 6 JOIN gpu_counter_track AS ct ON ct.id g.track_id AND ct.ugpu k.ugpu JOIN counter AS c ON c.track_id ct.id AND c.ts k.ts AND c.ts k.ts k.dur GROUP BY k.id, ct.name;这里有一个容易混淆的地方文档明确指出两个compute魔法数字 2 和 6 是不同的枚举——render_stage_category 2指 slice 的 render stage 分类而gpu_counter_group.group_id 6是GpuCounterGroup中 COMPUTE 计数器组的值。匹配逻辑是按ugpu找到同一 GPU 的计数器 track再取时间戳落在[kernel.ts, kernel.ts kernel.dur)窗口内的 counter 样本并同时算出SUM与AVG两种聚合供不同指标选用。第三段透视为一行一 kernel 的最终输出。SELECT k.launch_id AS id, k.kernel, ROUND(MAX(CASE WHEN kc.counter_name sm__throughput.avg.pct_of_peak_sustained_elapsed THEN kc.avg_v END), 1) AS compute_pct, ROUND(MAX(CASE WHEN kc.counter_name gpu__compute_memory_throughput.avg.pct_of_peak_sustained_elapsed THEN kc.avg_v END), 1) AS memory_pct, -- l1_pct / l2_pct / dram_pct 同理分别取 -- l1tex__throughput.avg.pct_of_peak_sustained_active、 -- lts__throughput.avg.pct_of_peak_sustained_elapsed、 -- gpu__dram_throughput.avg.pct_of_peak_sustained_elapsed 的 AVG CAST(MAX(CASE WHEN kc.counter_name gpc__cycles_elapsed.max THEN kc.sum_v END) AS INT) AS elapsed_cycles, CAST(MAX(CASE WHEN kc.counter_name sm__cycles_active.avg THEN kc.sum_v END) AS INT) AS active_cycles, CAST(IFNULL( MAX(CASE WHEN kc.counter_name gpu__time_duration.sum THEN kc.sum_v END), k.dur ) AS INT) AS dur_ns FROM _kernels AS k LEFT JOIN _kernel_counters AS kc ON kc.kernel_id k.id GROUP BY k.launch_id, k.kernel, k.dur ORDER BY k.dur DESC;l1_pct、l2_pct、dram_pct三列与compute_pct同构均为对应计数器名的AVG值。从 SQL 结构可以看出三条聚合规则与脚本头注释一致吞吐百分比与频率类指标用AVG窗口内样本均值周期数与时长用SUMgpc__cycles_elapsed.max、sm__cycles_active.avg、gpu__time_duration.sum在窗口内累加dur_ns用IFNULL(..., k.dur)兜底——trace 未提供gpu__time_duration.sum时回退到 slice 自身时长LEFT JOIN保证即使某 kernel 的计数器缺失也能出一行对应列为 NULL排序统一按dur DESC最长在内。5. 解读层四类判定与后续动作拿到数据后按通用解释层 speed_of_light.md 的判定矩阵读Compute Throughput 与 Memory Throughput 的相对关系两者都是 achieved-vs-theoretical 的 % of peak距 100% 的差距就是该天花板下未用尽的余量Compute 高、Memory 相对低 → compute-bound。计算单元是天花板杠杆在数学本身转到 compute_workload_analysis.md 找饱和的流水线并考虑更便宜的精度或减少工作量。NVIDIA 分支下nvidia/compute_workload_analysis.md会进一步给出alu/fma/fp16/fp32/fp64/tensor各 pipe 的利用率tensor_pct高说明已在张量核/矩阵路径上fma_pct/fp32_pct高说明受 FP32 算术限制可评估 fp16/bf16fp64_pct高说明双精度开销大alu_pct高则是整数/地址计算受限。Memory 高、Compute 相对低 → memory-bound。用缓存层级列定位它在哪一层dram_pct高 → DRAM 带宽瓶颈杠杆是局部性/复用tiling、fusion或更好的访问模式l2_pct/l1_pct高而dram_pct低 → 工作集由缓存供给杠杆是数据复用/工作集大小再次提醒这是吞吐占比不是命中率。两者都低 → latency/occupancy-bound。两条天花板都没接近峰值内核在 stall转到 occupancy.mdNVIDIA 分支nvidia/occupancy.md检查 block size 是否为 warp 大小NVIDIA 为 32的倍数、waves per SM 是否 1grid 太小填不满或 1–2尾部效应、Theoretical 与 Achieved Occupancy 的差距、以及哪个 Block Limitregisters/shared memory/warps/blocks/barriers是约束项。两者都高 → 接近真实天花板。内核已打包得很好进一步收益需要算法层面的改变而不是调参。健全性检查sanity checkactive_cycles远低于elapsed_cycles意味着计算单元在内核执行期间有大段时间空闲launch/调度间隙或尾部效应佐证 latency/occupancy 问题——这与判定 3 互为印证。最后要注意文档的免责边界任何数值阈值如high ≈ ≥ 60% of peak都只是经验法则rules of thumb并非厂商或插件定义的标准。6. 产出与对比报告要点和基线对比按工作流 Phase 3 的要求kernel_analysis.md一份合格的分析结论应包含三件事哪个 kernel—— 热点 kernel 的id、名字、dur_ns及占 GPU 时间的份额如已知bound 类型—— compute / memory / latency-occupancy附上数字Compute Throughput、Memory Throughput、Achieved Occupancy、饱和的 pipe具体杠杆—— 点名到可执行的改动提升占用率的启动配置改动block size、寄存器、shared memory、针对饱和 pipe 的精度/指令组合变化、或针对 memory-bound 的内存布局/局部性变化。对比两个 kernel优化前后或两个变体时跑同一套 Phase 2 脚本、对两个id的行做 diff 即可——因为每个脚本都一个 kernel 一行基线对比就是逐行对照。文档同时要求保留 SQL 与 kernel id 以便审计。7. 适用限制厂商覆盖当前 trace 中只有 NVIDIA 具备完整 Speed of Light 计数器集其他厂商只能使用其暴露的吞吐/时长数据做近似通用解释层仍然适用但具体计数器映射缺失见 speed_of_light.md 的 Get the data 一节。架构级峰值指导尚为预留nvidia/speed_of_light.md 末尾的 HTML 注释表明架构特定的峰值/杠杆指导例如 nvidia/h100/ 下对比 HBM 带宽、tensor TFLOPs 绝对峰值以及 FP8、TMA 等架构杠杆是once added的转发占位——从源码结构看当前仓库尚无该子目录读者在解读 % of peak 时只能相对比较不能据此文档得到具体硬件的绝对峰值。数据前提所有列依赖 trace 实际记录了 COMPUTE 计数器组group_id 6计数器缺失的 kernel 相应列为 NULLdur_ns会回退到 slice 时长此时该行的吞吐判定不可用但id/kernel/时长仍可与 kernels_summary.sql 的输出对齐。参考路径内容路径本文主题文档NVIDIA 分支ai/skills/perfetto/workflows/gpu/compute/nvidia/speed_of_light.md抽取 SQLai/skills/perfetto/workflows/gpu/compute/nvidia/scripts/speed_of_light.sql通用解释层判定矩阵ai/skills/perfetto/workflows/gpu/compute/speed_of_light.md工作流总入口Phase 1–3ai/skills/perfetto/workflows/gpu/compute/kernel_analysis.md全 kernel triage 脚本ai/skills/perfetto/workflows/gpu/compute/scripts/kernels_summary.sqlOccupancy 分支ai/skills/perfetto/workflows/gpu/compute/occupancy.md / nvidia 分支Compute Workload Analysis 分支ai/skills/perfetto/workflows/gpu/compute/compute_workload_analysis.md / nvidia 分支GPU 信息vendor/架构识别ai/skills/perfetto/workflows/gpu/gpu_info.mdtrace_processor CLI 参数docs/reference/trace-processor-cli.mdGPU 数据源背景docs/data-sources/gpu.md【免费下载链接】perfettoProduction-grade client-side tracing, profiling, and analysis for complex software systems.项目地址: https://gitcode.com/GitHub_Trending/pe/perfetto创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表