3、实时处理性能指标:帧率与延迟、带宽与吞吐量、软硬件协同
做ISP流水线,说白了就是在跟时间赛跑。你想想看,每一帧图像从Sensor出来,到最终显示在屏幕上,中间要经过几十个处理模块。任何一个环节慢了,整个系统就得卡住。
我个人习惯,拿到一个ISP项目,先不看算法多花哨,先把这几个性能指标算清楚。算不清楚,后面全是坑。
3.1 帧率(FPS)与延迟(Latency)要求
帧率,就是每秒能处理多少帧图像。手机拍照预览一般是30fps,专业相机能到60fps甚至120fps。但帧率不是越高越好,功耗会跟着涨。
延迟,是从Sensor曝光开始,到图像数据完全处理完的时间。这个指标在视频通话、自动驾驶里特别敏感。我遇到过一个问题:某款手机视频通话时,画面总是慢半拍。查到最后,是ISP管线里某个模块的延迟多了2ms。
关键公式:
- 帧周期 = 1 / 帧率。比如30fps,帧周期就是33.3ms。
- 管线总延迟 ≤ 帧周期,否则就会丢帧。
- 端到端延迟 = Sensor曝光 + ISP处理 + 显示刷新。
这里有个容易忽略的点:帧率是吞吐量的概念,延迟是响应时间的概念。高帧率不一定低延迟,低延迟也不一定高帧率。举个例子,流水线可以做到30fps,但每一帧要花50ms才能处理完——这就有问题了,因为下一帧已经在路上了。
| 场景 | 帧率要求 | 延迟要求 | 典型痛点 |
|---|---|---|---|
| 手机预览 | 30fps | < 50ms | 取景器卡顿 |
| 视频录制 | 30-60fps | < 100ms | 音画不同步 |
| 自动驾驶 | 15-30fps | < 30ms | 碰撞预警延迟 |
| 工业检测 | 60-120fps | < 16ms | 漏检 |
3.2 带宽(Bandwidth)与吞吐量(Throughput)计算
这两个词经常被混用,但在我眼里完全是两码事。
带宽,是总线或者DDR能提供的最大传输能力。比如LPDDR5能到6400Mbps,这是理论峰值。但实际能用到多少?我测过,一般只有60%-70%。
吞吐量,是ISP实际处理数据的速度。它受限于带宽,但更受限于处理单元的计算能力。
怎么算?我给你个公式:
// 以4K@30fps为例
分辨率 = 3840 × 2160 = 8.3M像素
每像素 = 2 bytes (RAW10/RAW12)
帧大小 = 8.3M × 2 = 16.6 MB
带宽需求 = 16.6 MB × 30fps = 498 MB/s
// 加上ISP内部多级buffer
// 实际带宽需求 ≈ 498 × 2.5 = 1245 MB/s
嗯,这里要注意。ISP内部不是只读一次写一次。每个模块都可能要读帧、写帧。我见过一个项目,工程师只算了原始带宽,结果DDR带宽被打满了,系统直接崩溃。
避坑指南:我曾经在一个4K@60fps的项目里,只算了Sensor到ISP的带宽,没算ISP内部各模块之间的带宽。结果ISP内部的AXI总线成了瓶颈。后来我养成了习惯:管线里每个模块的读写带宽都要单独算一遍。
3.3 实时性保障的软硬件协同机制
实时性不是靠硬件硬扛,也不是靠软件优化就能解决的。得软硬件一起上。
我画了一张图,你看完就明白了:
硬件层面,我强调确定性。每个模块的处理时间必须是固定的,不能有抖动。比如去噪模块,不管图像内容多复杂,都必须在1000个时钟周期内完成。做不到?那就加硬件资源。
软件层面,核心是动态调度。硬件是死的,但场景是活的。白天拍风景和晚上拍夜景,负载完全不同。软件要根据当前负载,动态调整各模块的工作频率和电压。
我的经验:软硬件协同的关键在于中断机制。硬件每处理完一帧,发一个中断给CPU。CPU收到中断后,立即调度下一帧的处理。这个中断响应时间,我建议控制在10us以内。超过这个数,帧率就会开始抖动。
最后说一个我踩过的坑。有一次,硬件Pipeline跑得很稳,但帧率就是上不去。查了三天,发现是驱动层的中断处理函数里,加了一个打印日志的语句。就这一行代码,把中断响应时间从5us拖到了50us。去掉之后,帧率立刻达标。
所以,实时性保障,说到底就是硬件做减法,软件做加法。硬件把能固定的都固定住,软件在固定的框架里做灵活调度。两者配合好了,才能既跑得快,又跑得稳。