性能分析工具(Profiling)用于采集和分析算子在昇腾AI处理器上运行阶段的关键性能指标,用户可根据输出的性能数据,快速定位软、硬件性能瓶颈,提升算子运行性能。
该功能可以与上板时间戳打点功能配套使用,通过timeline展示算子在每个核上的运行起始/终止时间等信息,方便更精准分析算子性能耗时。
通过命令行进行性能数据采集的关键步骤如下,详细样例参考上板Profiling数据采集。
ascendebug kernel --backend npu --profiling ... {其他NPU调测参数}
ascendebug kernel --backend npu --profiling ${profiling_metrics} ... {其他NPU调测参数}
AscendC::AscendCTimeStamp(descId);
ascendebug kernel --backend npu --dump-mode time_stamp --profiling ... {其他NPU调测参数}
ascendebug kernel --backend npu --dump-mode time_stamp --profiling ${profiling_metrics} ... {其他NPU调测参数}
其中${profiling_metrics}支持如下取值:
更多关于数据采集高级功能的介绍可参考《性能调优工具指南》的““采集AI任务运行性能数据””章节中--aic-metrics配置项。
当打屏日志中有调用msprof开启profiling的调用信息,并且有“npu kernel run end” 信息则表示Profiling执行完成。
通过API开启性能数据采集的关键步骤如下,详细样例参考上板Profiling数据采集。
本步骤仅适用于没有Tiling Info文件的场景,需调用Tiling调测API生成Tiling Info。
接口调用示例如下:
# 调用NPU编译接口 compile_npu_options = ascendebug.CompileNpuOptions() name, kernel_file, extern = op_executor.compile_custom_npu(customize_path, tiling_info.tiling_key, compile_npu_options) # 配置Profiling属性,调用Profiling运行接口 profiling_options = ascendebug.RunProfilingOptions(block_num=24, loop=10) npu_compile_info = ascendebug.NpuCompileInfo(syncall=extern['cross_core_sync'], task_ration=extern['task_ration']) op_executor.run_profiling(kernel_file, profiling_options, npu_compile_info=npu_compile_info, tiling_info=tiling_info)
AscendC::AscendCTimeStamp(descId);
# 调用NPU编译接口 compile_npu_options = ascendebug.CompileNpuOptions(dump_mode='time_stamp') name, kernel_file, extern = op_executor.compile_custom_npu(customize_path, tiling_info.tiling_key, compile_npu_options) # 配置Profiling属性,调用Profiling运行接口 profiling_options = ascendebug.RunProfilingOptions(block_num=24, loop=10) npu_compile_info = ascendebug.NpuCompileInfo(syncall=extern['cross_core_sync'], task_ration=extern['task_ration'], dump_mode='time_stamp) op_executor.run_profiling(kernel_file, profiling_options, npu_compile_info=npu_compile_info, tiling_info=tiling_info)
无论是命令行方式或API方式,Profiling解析结果存放在${root}/${work_dir}/npu/output路径下,其中${root}表示当前操作路径,${work_dir}表示调测工作空间,默认为/debug_workspace/${op_type}目录,${op_type}为算子名。目录结构示例如下,默认情况下采集到的文件如表1所示。
├ ${op_type} // 算子名 ├── npu │ ├── build // 存放NPU编译生成的中间文件 │ ├── launch_args.so │ ├── output // 存放NPU编译运行的输出文件及精度比对结果 │ ├── y.bin // 运行输出原始数据 │ ├── y.txt // 精度比对结果文件 │ ├── PROF_00000x_xxxx_xxx // 存放Profiling结果文件 │ ├── mindstudio_profiler_output │ ├── task_time_*.csv │ ├── prof_rule_*.json │ ├── op_summary_*.csv │ ├── op_statistic_*.csv │ ├── api_statistic_*.csv │ ├── step_trace_*.csv │ ├── step_trace_*.json │ ├── msprof_*.json // 若开启时间戳打点,会包含该信息 │ ├── src // 存放NPU编译生成的临时代码文件 │ ├── _gen_args_${op_type}.cpp
文件名 |
说明 |
备注 |
---|---|---|
task_time_*.csv |
Task Scheduler任务调度信息。 |
关于性能文件的详细介绍可参见《性能调优工具指南》中“性能数据文件参考”。 |
prof_rule_*.json |
调优建议。 |
|
op_summary_*.csv |
AI Core和AI CPU算子数据。 |
|
op_statistic _*.csv |
AI Core和AI CPU算子调用次数及耗时统计。 |
|
api_statistic_*.csv |
用于统计CANN层的API执行耗时信息。 |
|
step_trace_*.json |
(可选)迭代轨迹数据,每轮迭代的耗时。单算子场景下无此性能数据文件。 |
|
step_trace_*.csv |
(可选)迭代轨迹数据。单算子场景下无此性能数据文件。 |
|
msprof_*.json |
timeline数据总表。 说明:
若开启时间戳打点功能,生成的${root}/${work_dir}/npu/dump/PARSER_*/dump_data/${core_num}/time_stamp_core_${core_num}.csv文件会被解析并添加到msprof_*.json文件末尾。 |
|
注:“*”表示{timestamp}时间戳。 |
在Chrome浏览器中输入chrome://tracing,将文件拖到空白处打开,通过键盘上的快捷键(W:放大,S:缩小,A:左移,D:右移)查看。该文件可查看当前AI任务运行的时序信息,比如运行过程中接口调用时间线,如图1所示。
对于msprof_*.json,若开启时间戳打点功能,可通过timeline查看内置打点信息和自定义打点信息,打点位置在算子profiling中。
csv文件支持离线查看,可看到AI任务运行时的软硬件数据,比如各算子在AI处理器软硬件上的运行耗时,通过字段排序等可以快速找出需要的信息,如图2所示。
对于op_summary_*.csv,支持在线屏显summary关键字段信息(如下表),生成的字段由${profiling_metrics}取值控制,更多字段详细介绍参见《性能调优工具指南》中““op_summary(算子详细信息)””。
字段名 |
字段含义 |
profiling_metrics取值 |
---|---|---|
Task Duration |
Task耗时,包含调度到加速器的时间、加速器上的执行时间以及结束响应时间,单位us。 |
基础字段 |
Task Wait |
上一个Task的结束时间与当前Task的开始时间间隔,单位us。 |
|
aic_time |
当所有的Block被同时调度,且每个Block的执行时长相等时,该Task在AI Core上的理论执行时间,单位us。通常情况下,不同的Block开始调度时间略有差距,故该字段值略小于Task在AI Core上的实际执行时间。 当AI Core频率变化(比如进行手动调频、功耗超出阈值时动态调频以及Atlas 300V/Atlas 300I Pro产品)时该数据不准确,不建议参考。 |
|
aiv_time |
当所有的Block被同时调度,且每个Block的执行时长相等时,该Task在AI Vector Core上的理论执行时间,单位us。通常情况下,不同的Block开始调度时间略有差距,故该字段值略小于Task在AI Vector Core上的实际执行时间。(
--task-time=l1、--aic-mode=task-based时生成。 |
|
ai*_vec |
vec类型指令(向量类运算指令)耗时,单位us。 |
PipeUtilization |
ai*_mac |
cube类型指令(矩阵类运算指令)耗时,单位us。 |
|
ai*_scalar |
scalar类型指令(标量类运算指令)耗时,单位us。 |
|
ai*_fixp |
fixpipe类型指令(L0C->OUT/L1搬运类指令)耗时,单位us。 |
|
ai*_mte1 |
mte1类型指令(L1->L0A/L0B搬运类指令)耗时,单位us。 |
|
ai*_mte2 |
mte2类型指令(片上内存->AICORE搬运类指令)耗时,单位us。 |
|
ai*_mte3 |
mte3类型指令(AICORE->片上内存搬运类指令)耗时,单位us。 |
字段名 |
字段含义 |
profiling_metrics取值 |
---|---|---|
Task Duration |
Task耗时,包含调度到加速器的时间、加速器上的执行时间以及结束响应时间,单位us。 |
基础字段 |
Task Wait |
上一个Task的结束时间与当前Task的开始时间间隔,单位us。 |
|
aicore_time |
当所有的Block被同时调度,且每个Block的执行时长相等时,该Task在AI Core上的理论执行时间,单位us。通常情况下,不同的Block开始调度时间略有差距,故该字段值略小于Task在AI Core上的实际执行时间。 当AI Core频率变化(比如进行手动调频、功耗超出阈值时动态调频以及Atlas 300V/Atlas 300I Pro产品)时该数据不准确,不建议参考。 |
|
vec |
vec类型指令(向量类运算指令)耗时,单位us。
|
PipeUtilization |
mac |
cube类型指令(矩阵类运算指令)耗时,单位us。 |
|
scalar |
scalar类型指令(标量类运算指令)耗时,单位us。 |
|
mte1 |
mte1类型指令(L1->L0A/L0B搬运类指令)耗时,单位us。 |
|
mte2 |
mte2类型指令(DDR->AICORE搬运类指令)耗时,单位us。 |
|
mte3 |
mte3类型指令(AICORE->DDR搬运类指令)耗时,单位us。 |
字段名 |
字段含义 |
profiling_metrics取值 |
---|---|---|
Task Duration |
Task耗时,包含调度到加速器的时间、加速器上的执行时间以及结束响应时间,单位us。 |
基础字段 |
Task Wait |
上一个Task的结束时间与当前Task的开始时间间隔,单位us。 |
|
aicore_time |
当所有的Block被同时调度,且每个Block的执行时长相等时,该Task在AI Core上的理论执行时间,单位us。通常情况下,不同的Block开始调度时间略有差距,故该字段值略小于Task在AI Core上的实际执行时间。 当AI Core频率变化(比如进行手动调频、功耗超出阈值时动态调频以及Atlas 300V/Atlas 300I Pro产品)时该数据不准确,不建议参考。 |
|
vec |
vec类型指令(向量类运算指令)耗时,单位us。
|
PipeUtilization |
mac |
cube类型指令(矩阵类运算指令)耗时,单位us。 |
|
scalar |
scalar类型指令(标量类运算指令)耗时,单位us。 |
|
mte1 |
mte1类型指令(L1->L0A/L0B搬运类指令)耗时,单位us。 |
|
mte2 |
mte2类型指令(DDR->AICORE搬运类指令)耗时,单位us。 |
|
mte3 |
mte3类型指令(AICORE->DDR搬运类指令)耗时,单位us。 |
|
fixp |
fixpipe类型指令(L0C->OUT/L1搬运类指令)耗时,单位us。 |
PipelineExecuteUtilization |