S100 OpenExplorer

# #UCP Trace 使用说明

UCP trace通过在UCP执行的关键路径上嵌入trace记录，提供深入分析UCP应用程序调度逻辑的能力。在出现性能异常时，可以通过分析UCP trace，快速找到异常发生的时间点。

UCP trace提供了两种trace后端选项：`Perfetto Trace` 和 `Chrome Trace`。您可以通过设置环境变量，在这两者之间进行选择，以满足您特定的性能跟踪需求。

- `Perfetto Trace`可以获取到UCP记录的trace，以及系统状态，ftrace等信息。
- `Chrome Trace`只能获取UCP记录的trace ，主要用于分析UCP本身的调度逻辑。

UCP trace工具和配置文件位于`samples/ucp_tutorial/tools`路径下，目录结构为：

`tools/ └── trace # trace工具 ├── catch_trace.sh # chrome trace捕获脚本 ├── configs # 参考配置文件 │ ├── ucp_bpu_trace.cfg # 开启bpu trace的perfetto配置文件 | ├── ucp_dsp_trace.cfg # 开启dsp trace的perfetto配置文件 │ ├── ucp_in_process.cfg # in_process模式的perfetto配置文件 │ ├── ucp_in_process.json # in_process模式的ucp配置文件 │ ├── ucp_system.cfg # system模式的perfetto配置文件 │ └── ucp_system.json # system模式的ucp配置文件`

## #环境变量

环境变量 | 取值范围 | 默认值 | 说明
--- | --- | --- | ---
`HB_UCP_ENABLE_PERFETTO` | true，false | false | 是否启用Perfetto trace，true启动，false不启动，默认不启动。
`HB_UCP_PERFETTO_CONFIG_PATH` | Perfetto 配置文件路径 | "" | 指定pefetto配置文件的路径，默认为空，如果不配置该环境变量，则默认为system模式。
`HB_UCP_TRACE_LOG_LEVEL` | [0, 6] | 6 | 指定UCP Trace日志等级，默认为6，不输出。
`HB_UCP_USE_ALOG` | true，false | false | 是否启用alog sink，true启动，false不启动，默认不启动。启动alog sink之后会输出日志到alog buffer，使用logcat抓取日志，同时关闭日志输出到终端。

注解

Perfetto trace的优先级更高，如果`export HB_UCP_ENABLE_PERFETTO=true`的同时`export UCP_TRACE_LOG_LEVEL=0`，那么只启动Perfetto trace，忽略UCP trace日志级别。

## #UCP Trace 记录点

UCP在应用程序API及内部关键调度路径嵌入了trace记录，其中包括任务trace记录和算子trace记录。

### #任务 Trace 记录点

名称 | 说明
--- | ---
`hbDNNInfer` | 创建模型推理任务
`hbVPxxx` | 创建视觉处理任务
`hbHPLxxx` | 创建高性能计算任务
`hbUCPSubmitTask` | 任务提交
`${TaskType}::Wait` | 等待任务执行结束
`TaskSetDone` | 通知任务执行完成
`hbUCPReleaseTask` | 任务释放

### #算子 Trace 记录点

名称 | 说明
--- | ---
`SubmitOp` | 算子提交
`OpInfer` | 算子开始执行
`OpFnish` | 算子执行结束

## #Perfetto Trace

Perfetto 是Google开发和开源的系统性能分析工具，能够收集来自不同数据源的性能数据， 同时提供了`Perfetto UI`用于数据的可视化和分析。更多perfetto的详细信息，请参考 Perfetto 官方文档。

### #配置文件参数信息

#### #UCP trace配置文件参数信息

参数 | 数据类型 | 参数说明 | 关联参数
`backend` | string | 功能描述： in_process 表示进程内模式，进程内直接保存perfetto trace到文件。 system 表示系统模式，由后台服务traced，traced_probe统一进行trace捕获。 取值范围："in_process"，"system" | 无。
`trace_config` | string | 功能描述：该参数为protobuf文本格式的配置文件。 取值范围：perfetto 的配置文件路径。 | `backend`设置为"in_process"时，该参数才有效。

注解

UCP trace配置文件非必须指定，如果您的应用程序已经初始化了Perfetto，那么只需要`export HB_UCP_ENABLE_PERFETTO=true`即可开启Perfetto。

#### #Long trace配置文件参数信息

默认情况下，Perfetto将trace数据存储在内存中的缓冲区，直至trace会话终止时，才会将缓冲区的数据转储至文件。若trace数据量超出缓冲区容量，则无法保证数据的完整性。

Perfetto支持周期性地将缓冲区的数据写入到文件中，只需在trace配置文件中增加以下字段即可。

参数 | 数据类型 | 参数配置说明
--- | --- | ---
`write_into_file` | bool | `true`表示开启日志周期性写入到文件，默认`false`，不开启。
`file_write_period_ms` | uint32 | 设置写入文件的周期，默认值为`5s`。您可根据每秒生成数据的大小和trace缓冲区容量来设置合适的写入周期。
`max_file_size_bytes` | uint64 | 设置trace文件的最大值，当超过该值后，trace将自动终止，默认无限制。

### #配置文件模板

#### #UCP Trace 配置文件模板

用于配置UCP如何使用Perfetto，您可以通过环境变量`HB_UCP_PERFETTO_CONFIG_PATH`来指定。

##### #in_process 模式

ucp_in_process.json
`{ "backend": "in_process", "trace_config": "ucp_in_process.cfg" }`

##### #system 模式

ucp_system.json
`{ "backend": "system" }`
注解

`backend`选择`system`时，无需单独为UCP指定`trace_config`。

#### #Perfetto 配置文件模板

关于Perfetto配置文件的详细信息可以参考 Perfetto TraceConfig Reference。 UCP提供了参考配置文件`ucp_in_process.cfg`和`ucp_system.cfg`，您可根据应用场景进行修改。

ucp_in_process.cfg
`# Enable periodic flushing of the trace buffer into the output file. write_into_file: true # Output file path output_path: "ucp.pftrace" # Sampling duration: 10s duration_ms: 10000 # Writes the userspace buffer into the file every 2.5 seconds. file_write_period_ms: 2500 buffers { # buffer size size_kb: 65535 # DISCARD: no new sampling data will be stored when the storage is full. # RING_BUFFER: old sampling data will be discarded and new data will be stored when the storage is full. fill_policy: RING_BUFFER } # UCP data source data_sources: { config { name: "track_event" track_event_config { enabled_categories: "dnn" } } }`

#### #BPU Trace配置文件模板

在system模式下支持抓取BPU trace，只需在perfetto配置文件中加入BPU trace的数据源即可，`ucp_bpu_trace.cfg`中已默认添加了BPU trace数据源，具体配置项如下所示：

ucp_bpu_trace.cfg
`data_sources: { config { name: "linux.sys_stats" sys_stats_config { bputrace_period_ms: 500 } } }`

`bputrace_period_ms`用于设置读取BPU trace的周期，您可根据实际使用场景调整该参数，当BPU负载较大时，可以适当缩短读取周期，避免发生因读写速度不匹配导致的trace数据被覆盖的问题。

注解

当前BPU Trace功能暂不支持运行时动态开启，若需在应用运行期间实时捕获BPU Trace数据，需在应用启动前通过命令手动开启该功能，具体操作指令为：`echo 1 > /sys/devices/system/bpu/bpu0/trace`， 执行该命令前需要确保 `/sys/devices/system/bpu/bpu0/power_enable` 的值为0，如果不为0，请先执行 `echo 0 > /sys/devices/system/bpu/bpu0/power_enable`。

#### #DSP Trace配置文件模板

在system模式下支持抓取DSP trace，只需在perfetto配置文件中加入DSP trace的数据源即可，`ucp_dsp_trace.cfg`中已默认添加了DSP trace数据源，有效配置项如下所示：

ucp_dsp_trace.cfg
`data_sources { config { name: "linux.sys_stats" sys_stats_config { dsptrace_period_ms: 500 } } }`

`dsptrace_period_ms`用于设置读取DSP trace的周期，您可根据实际使用场景调整该参数，当DSP负载较大时，可以适当缩短读取周期，避免发生因读写速度不匹配导致的trace数据被覆盖的问题。

注解

当前DSP Trace功能暂不支持运行时动态开启，若需在应用运行期间实时捕获DSP Trace数据，需在应用启动前通过命令手动开启该功能，参考操作指令如下：

`# stop vdsp fw echo stop > /sys/class/remoteproc/remoteproc1/state # stop or start dsp trace echo 0 > /sys/devices/virtual/misc/vdsp0/vdsp_ctrl/trace_switch echo 1 > /sys/devices/virtual/misc/vdsp0/vdsp_ctrl/trace_switch # check dsp trace status cat /sys/devices/virtual/misc/vdsp0/vdsp_ctrl/trace_switch`

### #使用示例

#### #UCP trace示例

in_process模式抓取进程内trace信息

in_process模式下只能抓取UCP进程内的trace信息，可以不用启动perfetto的后台进程。具体操作步骤如下：

1. 配置环境变量。

`# 指定 ucp perfetto 配置路径。 export HB_UCP_PERFETTO_CONFIG_PATH=ucp_in_process.json # 开启 perfetto 功能。 export HB_UCP_ENABLE_PERFETTO=true`
注解

`ucp_in_process.json`中指定了Perfetto的配置文件`ucp_in_process.cfg`，其中`output_path`指定了trace文件的输出路径。由于Perfetto不支持直接覆盖原有的trace文件，若该文件已经存在，则需要先将其删除。

2. 运行UCP应用程序，这里以`hrt_model_exec`为例。

注解

由于指定的文件路径是相对路径，因此trace配置文件和脚本需要放置在运行程序的同级目录下。同时，需要确保在同一个shell环境中配置环境变量和运行程序。

`./hrt_model_exec perf \ --model_file resnet50_224x224_nv12.hbm \ --frame_count 1000 \ --thread_num 8`

3. 生成的trace保存在 `ucp.pftrace`，您可以使用 Perfetto UI 打开。

4. 在时间线上点击创建的任务，可以看到任务从创建到释放的完整调度流程。

5. Perfetto UI常用操作如下，更详细的操作说明，请参考`help`界面。

   操作 | 说明
   --- | ---
   `w` 或 ctrl+鼠标滚轮上滑 | 放大
   `s` 或 ctrl+鼠标滚轮下滑 | 缩小
   `a` 或 向左拖动上方的时间条 | 左移
   `d` 或 向右拖动上方的时间条 | 右移
   `?` | 打开 help 界面

system模式抓取进程内trace信息

system模式下，UCP trace只是其中的一个数据源，因此需要运行`tracebox`相对应的指令来完成trace的捕获。具体操作步骤如下：

1. 运行Perfetto后台进程。

`# 启动 trace 服务。 # 只需要启动一次，如果已经启动，则不需要再次启动。 tracebox traced --background # 运行数据捕获服务。 # 只需要启动一次，如果已经启动，则不需要再次启动。 tracebox traced_probes --background --reset-ftrace`

2. 触发数据抓取。

`# -c：指定perfetto 配置文件。 # -o：指定输出trace数据文件路径。 tracebox perfetto --txt -c ucp_system.cfg -o ucp.pftrace`

3. 另起一个终端，配置UCP环境变量。

`# 默认不指定HB_UCP_PERFETTO_CONFIG_PATH时，为system模式。 # 如果不生效，可能是当前版本不支持自动选择，需要显式地指定system的配置文件。 export HB_UCP_PERFETTO_CONFIG_PATH=ucp_system.json # 开启 perfetto 功能。 export HB_UCP_ENABLE_PERFETTO=true`

4. 运行UCP应用程序，这里以`hrt_model_exec`为例。

注意

为了能够抓取完整的数据，需要确保`hrt_model_exec`执行结束前，`perfetto`进程未退出。

`./hrt_model_exec perf \ --model_file resnet50_224x224_nv12.hbm \ --frame_count 1000 \ --thread_num 8`

5. 生成的trace保存在`perfetto`命令指定的输出文件`ucp.pftrace`，您可以使用 Perfetto UI 打开。

#### #BPU Trace示例

为了展示多个模型推理过程中的BPU trace，这里提供了一个多进程应用的示例。除了启动的运行程序有所不同外，其余的步骤与前一章节相同。

`./hrt_model_exec perf \ --model_file resnet50_224x224_nv12.hbm \ --frame_count 50 \ --thread_num 1 & \ ./hrt_model_exec perf \ --model_file googlenet_224x224_nv12.hbm \ --frame_count 50 \ --thread_num 1 \`

BPU Trace的可视化需要使用地平线定制开发的`hbperfetto`工具进行打开，您可以通过联系地平线系统软件技术支持人员来获取该工具。使用`hbperfetto`打开trace文件的效果如下图所示：

BPU Trace中所呈现的不同模型推理任务的调度情况如下图所示：

`hbperfetto` 支持UCP trace和BPU trace的关联。以下图示展示了从UCP模型推理任务的创建，提交，调度执行，直至任务完成执行并最终释放的完整流程。

此外，您可通过SQL查询BPU trace的原始数据。

`select * from bpu_trace`

### #常用数据源介绍

事件类型 | 数据源名称 | hbperfetto定制 | 配置 | 说明
--- | --- | --- | --- | ---
应用的track事件 | `track_event` | 否 | `track_event_config` | 用于抓取应用程序通过调用perfetto sdk api进行埋点的数据。
ftrace | `linux.ftrace` | 否 | `ftrace_config` | 通过ftrace_events指定抓取的事件，比如`sched/sched_switch`，具体支持的事件可通过`/sys/kernel/tracing/available_events`查看，`ftrace_config` 的详细说明请参考 FtraceConfig。
系统内存 | `linux.sys_stats` | 否 | `sys_stats_config` | 通过 `meminfo_period_ms` 设置采样周期，`meminfo_counters`设置抓取的数据类型，比如`MEMINFO_MEM_AVAILABLE`，`sys_stats_config` 的详细说明请参考 SysStatsConfig。
进程内存 | `linux.process_stats` | 否 | `process_stats_config` | 通过 `proc_stats_poll_ms` 设置采样周期，`process_stats_config` 的详细说明请参考 ProcessStatsConfig。
CPU占用 | `linux.sys_stats` | 否 | `sys_stats_config` | 通过 `stat_period_ms` 设置采样周期。
perf | `linux.perf` | 否 | `perf_event_config` | 记录进程调用栈和perf计数，`perf_event_config` 的详细说明请参考 PerfEventConfig。
DDR带宽 | `linux.sys_stats` | 是 | `sys_stats_config` | 记录ddr读写带宽，通过 `ddrinfo_period_ms` 设置采样周期。
ION内存 | `linux.sys_stats` | 是 | `sys_stats_config` | 记录ION内存信息，通过 `ion_period_ms` 设置采样周期。
BPU占用 | `linux.sys_stats` | 是 | `sys_stats_config` | 记录BPU占用率，通过 `bpuinfo_period_ms` 设置采样周期。
BPU trace | `linux.sys_stats` | 是 | `sys_stats_config` | 记录BPU trace信息，通过 `bputrace_period_ms` 设置采样周期。
DSP trace | `linux.sys_stats` | 是 | `sys_stats_config` | 记录DSP trace信息，通过 `dsptrace_period_ms` 设置采样周期。

## #Chrome Trace

Chrome trace只支持捕获UCP trace，不支持多数据源的捕获，多数据源的捕获请使用Perfetto trace。Chrome trace的特点是简单，易用， 使用文本日志来记录trace，不依赖于额外的三方库和工具。如果只关心UCP的调度逻辑，可以使用Chrome trace来进行捕获。

### #使用示例

1. 配置环境变量。

`# 关闭 perfetto export HB_UCP_ENABLE_PERFETTO=false # 设置 UCP Trace 的日志级别为 0。 export HB_UCP_TRACE_LOG_LEVEL=0 # 设置 UCP 日志保存的文件路径。 export HB_UCP_LOG_PATH=ucp_log.txt`
注解

在开始新的捕获前，建议先删除旧的日志文件，避免旧的数据带来的干扰。

2. 运行UCP应用程序，这里以`hrt_model_exec`为例。

`./hrt_model_exec perf \ --model_file resnet50_224x224_nv12.hbm \ --frame_count 1000 \ --thread_num 8`

3. 执行trace抓取脚本。

在完成trace日志的捕获后，运行UCP发布包中提供了`catch_trace.sh`，将原始的trace日志转换为json格式的trace文件。

`# -i: 指定输入trace日志文件。 # -o: 指定输出json格式的trace日志。 ./catch_trace.sh -i ucp_log.txt -o ucp_trace_task.json # 默认以任务视角可视化trace，您也可以切换为线程视角。 # -m: 指定转换模式，task: 任务视角（默认），thread: 线程视角。 ./catch_trace.sh -m thread -i ucp_log.txt -o ucp_trace_thread.json`

4. 使用 Perfetto UI打开 `ucp_trace_task.json` 和 `ucp_trace_thread.json`。

Perfetto UI 打开 `ucp_trace_thread.json`：

页面目录