不是线程越多越快:用 hrt_model_exec 在 J6M 上给 YOLOv5x 建立性能基线
同一个 HBM,在单线程和多线程下,平均延时、FPS、BPU 耗时的含义并不一样。更容易踩坑的是,把模型加载时间、单帧推理时间和应用端到端时延混到一起。
确认 HBM 真正需要的输入;
建立单线程延时基线;
找到单 BPU 核模型的合理并行度。
测试环境
项目 | 本次实测配置 |
|---|---|
开发板 | J6M |
系统 | Linux 6.1.134-rt51,aarch64 |
UCP / HBRT | UCP 3.12.1 / HBRT 4.4.6 |
模型 | yolov5x_640x640_nv12.hbm |
模型输入 | NV12,640×640 |
编译核数 | 1 |
测试输入 | input_bus.jpg |
测试帧数 | 1000 |
第一步:先看模型输入
执行:

图 1:model_info 输出截图
模型并不是一个普通的 RGB 单输入模型。它有两路 NV12 输入:
Y 平面大小是 640×640,UV 平面是 320×320×2。两路输入的 stride 都是动态的。
因此,拿一张 JPG 做冒烟推理时,需要把同一个文件传入两次,并显式声明它们分别用于 Y 和 UV:

图 2:infer 输出截图
工具输出了以下信息:
这里有两个值得记录的细节。
第二步:随机输入和真实图片,差别有多大?
我先跑了一组随机输入基线:
随后使用真实图片再跑一组:
结果如下:
输入方式 | 平均延时 | FPS |
|---|---|---|
工具构造的随机输入 | 10.274 ms | 96.804 |
input_bus.jpg 的 NV12 输入 | 10.281 ms | 96.744 |
两组平均延时相差 0.0077 ms,约为 0.07%。对这个固定输入尺寸的 YOLOv5x HBM 而言,随机输入和真实图片输入给出的模型性能基线基本一致。
不过这个结论只适用于本次模型和测试条件,不能推广到所有模型。遇到动态控制流、ROI、索引类输入或输入范围敏感算子时,仍应优先用真实输入测试。
第三步:单线程延时和并行吞吐要分开测
真实图片输入下,单线程 1000 帧测试结果为:
thread_num | 平均延时 | FPS |
|---|---|---|
1 | 10.281 ms | 96.744 |
2 | 19.844 ms | 100.397 |
4 | 39.680 ms | 100.406 |
8 | 79.300 ms | 100.393 |
16 | 158.068 ms | 100.388 |
结果很直观:
从 1 线程升到 2 线程,FPS 从 96.744 提升到 100.397,增幅约 3.8%;
线程数继续增加,FPS 基本停在 100.4 左右;
单个请求的平均延时则持续增加,16 线程时达到 158.068 ms。
2 线程的 profile 也能看到这个现象:
该组的最小 BPU 段耗时为 10.361 ms,接近单线程基线;平均值接近 20 ms,说明部分任务在单核上发生了排队。
因此,本模型的配置建议是:
目标 | 推荐配置 |
|---|---|
单路请求低延时 | thread_num=1 |
单核吞吐接近上限 | thread_num=2 |
thread_num>=4 | 不建议用于该模型,吞吐没有实际提升 |
用 hrt_model_exec 建立基线后,还该做什么?
这次测试只回答了模型执行层的问题:
HBM 输入是什么;
单帧模型延时约是多少;
单核 BPU 能跑到多少吞吐;
增加线程后是否还有效。
如果实际应用的端到端帧率远低于约 100 FPS,排查范围就更清楚了:问题不在这个 HBM 的单核执行上,需要继续看图片处理、后处理、CPU 任务、多个模型争抢 BPU,或者应用 Pipeline 调度。
