一 背景回顾
上篇立了 flag:19.5fps 到 30fps 靠流水线优化。这篇填坑——profiling 做完发现,模型相关(预处理+推理+后处理)一共只跑 8.71ms,真正的瓶颈根本不在推理!
二 Profiling 过程
插桩打印这些阶段耗时如下:
| 阶段 | 耗时(ms) | 占比 |
|---|---|---|
| 视频解码 | 13.85 | 30% |
| 颜色空间转换(NV12->RGB) | 4.23 | 9% |
| 手掌模型预处理 | 1.48 | 3% |
| 手掌检测推理 | 0.71 | 2% |
| 手掌检测后处理 | 0.04 | <1% |
| 关键点模型预处理 | 3.45 | 7% |
| 关键点检测 | 1.17 | 2% |
| 关键点后处理 | 1.9 | 4% |
| 显示提交 | 18.64 | 41% |
这彻底颠覆我之前的想象,模型相关(预处理+推理+后处理)一共 8.71ms,占不到 20%!时间主要花费在显示提交和视频解码部分。
三 显示提交-同步等待改异步
屏幕设置是 2K/60Hz,显示提交时间花费原因是:为快速实现上屏验证,我用单 buffer+提交同步等待,60Hz 的 vsync 大概 16.67ms,同步提交需要等显示控制器扫描 buffer 到下一个 vsync 到来才返回。改用显示双缓冲 buffer+异步提交等待,现在满足 30fps 要求。
四 优化前后对照
显示双缓冲 buffer+异步提交等待机制把时间从 18.64 降到 4.15ms,同时在画面上叠加了各阶段耗时和帧率的 OSD 信息,下面是抓取第 100 帧和 230 帧的结果:
图1:第100帧解码视频dump
图2:第230帧解码视频dump
可以看到,帧率稳定在 30fps,同时解码时间(dec)仍比较大,下一步继续优化。
五 总结和后续
显示双缓冲 buffer+异步提交等待解决了显示时间长的问题,对视频解码耗时分解后发现,解码那 13.85ms 里我们又发现了新东西——真解码只占零头,大头花在了一个意想不到的地方,下期细讲,目标 60fps!