优化 FPS 和延迟
优化 FPS 和延迟
pipeline.setXLinkChunkSize(0))。有关代码示例,请参阅 延迟测量。要启用 10Gbps USB3 模式(使用 USB 3.2 Gen 2 兼容线缆时),您必须在 Device 构造函数中显式设置它:
Python
1with dai.Device(pipeline, maxUsbSpeed=dai.UsbSpeed.SUPER_PLUS) as device:| What | Resolution | FPS | FPS set | Latency [ms] | Bandwidth | Histogram |
|---|---|---|---|---|---|---|
| Color (isp) | 1080P | 60 | 60 | 33 | 1.5 Gbps | link |
| Color (isp) | 4K | 28.5 | 30 | 150 | 2.8 Gbps | link |
| Color (isp) | 4K | 26 | 26 | 83 (Std: 3.6) | 2.6 Gbps | / |
| Mono | 720P/800P | 120 | 120 | 24.5 | 442/482 Mbps | link |
| Mono | 400P | 120 | 120 | 7.5 | 246 Mbps | link |
- oak_bandwidth_test.py 结果:下行 797 mbps,上行 264 mbps。
- oak_latency_test.py 结果:平均值:5.2 ms,标准差:6.2。
| What | Resolution | FPS | FPS set | PoE Latency [ms] | USB Latency [ms] | Bandwidth |
|---|---|---|---|---|---|---|
| Color (isp) | 1080P | 25 | 25 | 51 | 33 Std: 0.8 | 622 Mbps |
| Color (isp) | 4K | 8 | 8 | 148 | 80 Std: 1.2 | 530 Mbps |
| Color (isp) | 4K | 8.5 | 10 | 530 | 80 Std: 1.3 | 663 Mbps |
| Mono | 400P | 90 | 90 | 12 Std: 5.0 | 8 Std: 0.47 | 184 Mbps |
| Mono | 400P | 110 | 110 | 16 Std: 9.4 | 8 Std: 0.45 | 225 Mbps |
- 延迟测量的是帧时间戳 (
imgFrame.getTimestamp()) 和帧在主机上接收时的时间戳 (dai.Clock.now()) 之间的时间。 - Histogram 显示了从帧到主机的时间每帧的变化情况。Y 轴表示在该时间发生的帧数,X 轴表示微秒。
- Bandwidth 是以指定 FPS 流式传输指定帧所需的计算带宽。
编码帧
| What | Resolution | FPS | FPS set | Time-to-Host [ms] | Histogram |
|---|---|---|---|---|---|
| Color video H.265 | 4K | 28.5 | 30 | 210 | link |
| Color video MJPEG | 4K | 30 | 30 | 71 | link |
| Color video H.265 | 1080P | 60 | 60 | 42 | link |
| Color video MJPEG | 1080P | 60 | 60 | 31 | link |
| Mono H.265 | 800P | 60 | 60 | 23.5 | link |
| Mono MJPEG | 800P | 60 | 60 | 22.5 | link |
| Mono H.265 | 400P | 120 | 120 | 7.5 | link |
| Mono MJPEG | 400P | 120 | 120 | 7.5 | link |
message_zero_copy 分支上的所有功能并非都可用)PoE 延迟
- 网络本身。例如,如果您在一个拥有许多节点的庞大网络中,与使用直接连接相比,延迟会更高。
- 存在带宽瓶颈:
- 计算机的网卡设置,文档在此
- 100% OAK Leon CSS(CPU)使用率。Leon CSS 核心负责 POE 通信(参见此处文档),如果 CPU 使用率达到 100%,它将无法像应有的那样快速处理通信。解决方法: 请参阅 CPU 使用率 文档。
- 提高 PoE 延迟的另一种潜在方法是微调网络设置,例如 MTU、TCP 窗口大小等(此处 获取更多信息)
带宽
Command Line
14K NV12/YUV420 帧:3840 * 2160 * 1.5 * 30fps * 8bits = 3 gbps
21080P NV12/YUV420 帧:1920 * 1080 * 1.5 * 30fps * 8bits = 747 mbps
3720P NV12/YUV420 帧:1280 * 720 * 1.5 * 30fps * 8bits = 331 mbps
4
51080P RGB 帧:1920 * 1080 * 3 * 30fps * 8bits = 1.5 gbps
6
7800P 深度帧:1280 * 800 * 2 * 30fps * 8bits = 492 mbps
8400P 深度帧:640 * 400 * 2 * 30fps * 8bits = 123 mbps
9
10800P 单声道帧:1280 * 800 * 1 * 30fps * 8bits = 246 mbps
11400P 单声道帧:640 * 400 * 1 * 30fps * 8bits = 62 mbps- 使用设备上的 VideoEncoder 对帧(H.264、H.265、MJPEG)进行编码
- 降低 FPS/分辨率/流的数量
测量操作时间
trace(参见 DepthAI 调试级别),depthai 将记录每个节点/进程的操作时间,如下所示。Command Line
1[SpatialDetectionNetwork(1)] [trace] SpatialDetectionNetwork 同步耗时 '70.39142' ms。
2[StereoDepth(4)] [trace] Warp 节点耗时 '2.2945' ms。
3[system] [trace] EV:0,S:0,IDS:27,IDD:10,TSS:2,TSN:601935518
4[system] [trace] EV:0,S:1,IDS:27,IDD:10,TSS:2,TSN:602001382
5[StereoDepth(4)] [trace] Stereo 耗时 '12.27392' ms。
6[StereoDepth(4)] [trace] 'Median+Disparity to depth' 流水线耗时 '0.86295' ms。
7[StereoDepth(4)] [trace] Stereo 后处理(总计)耗时 '0.931422' ms。
8[SpatialDetectionNetwork(1)] [trace] NeuralNetwork 推理耗时 '62.274784' ms。
9[StereoDepth(4)] [trace] Stereo 校正耗时 '2.686294' ms。
10[MonoCamera(3)] [trace] Mono ISP 耗时 '1.726888' ms。
11[system] [trace] EV:0,S:0,IDS:20,IDD:25,TSS:2,TSN:616446812
12[system] [trace] EV:0,S:1,IDS:20,IDD:25,TSS:2,TSN:616489715
13[SpatialDetectionNetwork(1)] [trace] DetectionParser 耗时 '3.464118' ms。运行 NN 时降低延迟
增加 NN 资源
Python
1import depthai as dai
2
3pipeline = dai.Pipeline()
4# nn = pipeline.createNeuralNetwork()
5# nn = pipeline.create(dai.node.MobileNetDetectionNetwork)
6nn = pipeline.create(dai.node.YoloDetectionNetwork)
7nn.setNumInferenceThreads(1) # 默认使用 2 个线程
8nn.setNumNCEPerInferenceThread(2) # 默认,每个线程使用 1 个 NCEAVAILABLE_SHAVES / 2。YoloV7-tiny 的 FPS 和延迟比较示例:| NN 资源 | Camera FPS | 延迟 | NN FPS |
|---|---|---|---|
| 6 个 SHAVE,2 个线程(1 个 NCE/线程) | 15 | 155 毫秒 | 15 |
| 6 个 SHAVE,2 个线程(1 个 NCE/线程) | 14 | 149 毫秒 | 14 |
| 6 个 SHAVE,2 个线程(1 个 NCE/线程) | 13 | 146 毫秒 | 13 |
| 6 个 SHAVE,2 个线程(1 个 NCE/线程) | 10 | 141 毫秒 | 10 |
| 13 个 SHAVE,1 个线程(2 个 NCE/线程) | 30 | 145 毫秒 | 11.6 |
| 13 个 SHAVE,1 个线程(2 个 NCE/线程) | 12 | 128 毫秒 | 12 |
| 13 个 SHAVE,1 个线程(2 个 NCE/线程) | 10 | 118 毫秒 | 10 |
将摄像头 FPS 降低到与 NN FPS 匹配
- MIPI 读取
- ISP 处理
- 预览后处理
- NN 处理
- 流式传输到主机
- 最后,最终到达应用程序的额外延迟
NN 输入队列大小和阻塞行为
detNetwork.input.setBlocking(False),但队列大小未更改,则以下调整可能有助于提高延迟性能:通过添加 detNetwork.input.setQueueSize(1),同时将摄像头 FPS 设置回 40,我们获得约 80..105 毫秒的延迟。 非确定性行为的原因之一是摄像头以不同的速率(25 毫秒帧时间)生成,而 NN 已完成并可以接受新帧进行处理。