009、影像系统DDR带宽分配策略:多摄并发与AI算法同时运行时的带宽争抢与优化 009、影像系统DDR带宽分配策略多摄并发与AI算法同时运行时的带宽争抢与优化去年年底在给某款旗舰机型调双主摄AI夜景模式的时候遇到一个特别诡异的现场问题。相机预览界面在切换镜头的那一瞬间画面会卡顿大概三百毫秒但更致命的是后台同时跑着的人脸检测框直接“飞”了——检测框的坐标和实际人脸位置差了半个屏幕。一开始我们怀疑是传感器同步问题查了三天最后用总线监测工具一看DDR带宽在切换瞬间被拉到了95%以上CPU和NPU的请求全部被堵在队列里ISP的line buffer直接饿死画面断层就是这么来的。这个问题其实特别典型多摄并发加AI算法同时跑本质上是把DDR带宽当成一个共享的“水管”谁都想多吸一口但水管就那么大。高通Spectra、联发科Imagiq、海思ISP各家对带宽的管理思路完全不一样但底层逻辑是相通的——你得知道谁在吃带宽吃多少什么时候吃以及怎么让它在关键时候让路。先掰扯一下影像系统里DDR带宽的消耗大户。第一是ISP本身尤其是多摄并发的时候每个sensor都在往DDR里写RAW数据ISP从DDR里读RAW处理完再写回YUV或RAW这中间还有3A统计数据的读写。第二是NPU跑AI模型的时候权重和中间特征图都是DDR大户尤其是那种大分辨率输入的人脸检测模型一次推理的DDR访问量轻松上GB级别。第三是显示和视频编码预览要往显示控制器送数据录像要往编码器送数据这些虽然单次访问量不大但频率极高而且有实时性要求卡一帧就是掉帧。多摄并发的时候带宽争抢最激烈的地方其实在ISP的写回阶段。比如双摄同时出图两个ISP pipeline都在往DDR里写RAW如果平台的总线仲裁策略是公平轮询那每个ISP分到的带宽就是一半看起来公平但实际上一旦NPU开始跑模型它的大块burst访问会直接把总线占满ISP的写回请求被无限期延后导致ISP内部buffer溢出只能丢帧或者等下一帧。这里踩过坑——别指望硬件总线仲裁能自动解决优先级问题它只保证不饿死不保证实时性。高通Spectra平台的做法是引入了“QoS优先级”的概念每个总线主设备可以设置一个优先级等级ISP的写回请求可以设置成高优先级NPU的访问设置成中优先级显示控制器设置成最高优先级。但这里有个坑QoS优先级不是全局的它是分区域的比如ISP的写回请求在某个DDR通道上是高优先级但到了另一个通道上可能就变成低优先级了。所以调优的时候你得先搞清楚你的数据流走的是哪个通道别想当然地以为设置了高优先级就万事大吉。联发科Imagiq平台的思路不太一样它更强调“带宽预算”的概念。你在初始化ISP的时候可以给每个pipeline分配一个固定的带宽上限比如主摄RAW写入带宽上限是2GB/s副摄是1GB/sNPU是1.5GB/s。这样做的优点是确定性很强不会出现某个模块突然把带宽吃满的情况但缺点是灵活性差如果某个场景下主摄需要更多带宽比如开启HDR而副摄闲着你没法动态调整。所以联发科的方案里你得在软件层面做动态带宽重分配这就要用到它的“bandwidth manager”接口可以在运行时修改每个模块的带宽上限。海思ISP平台在带宽管理上更“硬核”一些它直接在硬件层面做了“带宽隔离”——每个模块有独立的DDR通道物理上隔离互不干扰。这个方案在安防和车载领域特别吃香因为那些场景对确定性要求极高宁可牺牲一点带宽利用率也要保证关键模块不卡顿。但缺点是成本高DDR通道数量有限多摄并发的时候通道不够用你就得把两个模块塞到同一个通道里这时候又回到了争抢的问题。瑞芯微和安霸平台相对简单一些它们更依赖CPU侧的软件调度。比如瑞芯微的RK3588它的ISP和NPU之间没有硬件级的带宽仲裁全靠Linux内核的DMA-BUF和ION内存管理来协调。这种方案的优点是灵活你可以完全掌控带宽分配逻辑但缺点是性能上限低一旦并发压力大软件调度的开销本身就占用不少CPU周期反而加剧了带宽压力。说回实战调优。我总结了一套“三步走”的带宽分配策略适用于大多数平台。第一步是“摸清家底”。用平台自带的性能监测工具比如高通的Perfetto、联发科的Systrace、海思的Profiler把每个模块在典型场景下的DDR带宽占用曲线拉出来。注意一定要测“峰值”而不是“平均值”因为带宽争抢发生在峰值时刻。比如跑AI模型的时候NPU的带宽占用是脉冲式的峰值可能是平均值的三倍如果你按平均值做预算峰值一来就崩了。第二步是“定优先级”。根据业务场景把模块分成“硬实时”、“软实时”和“尽力而为”三档。硬实时模块包括显示控制器、ISP的写回、视频编码器的输入这些一旦卡顿就是掉帧或花屏必须保证带宽。软实时模块包括NPU推理、3A统计、人脸检测框绘制这些可以容忍一定的延迟但不能丢数据。尽力而为模块包括缩略图生成、后台图像分析这些可以随时降级或暂停。优先级定好之后在硬件层面设置QoS在软件层面设置带宽预算双管齐下。第三步是“动态调整”。这一步最关键也最容易踩坑。静态的优先级和预算只能保证“不崩”但没法保证“最优”。比如在夜景模式下主摄需要更多带宽来跑多帧降噪这时候副摄的带宽预算就应该降下来甚至可以把副摄的ISP pipeline暂时挂起。这个动态调整逻辑一定要放在一个独立的“带宽管理线程”里不要放在ISP的中断回调里因为中断回调里做复杂逻辑容易导致中断超时引发更严重的问题。别这样写——在ISP回调里直接调用带宽管理接口你会把整个pipeline卡死的。还有一个容易被忽略的点就是DDR的page policy。很多平台支持DDR的page open/close策略如果设置成“page close”每次访问都需要重新打开page延迟高但带宽利用率高如果设置成“page open”延迟低但带宽利用率低。对于影像系统来说建议设置成“page open”因为影像数据流的访问模式是顺序的page open能显著降低延迟而且带宽利用率虽然低一点但影像系统对延迟更敏感。最后给点个人经验。第一多摄并发加AI的场景不要指望硬件仲裁能解决所有问题一定要在软件层面做带宽预算和动态调整。第二调带宽的时候别只盯着DDR带宽还要关注总线协议转换的开销比如AXI到CHI的转换有时候带宽没满但延迟很高就是协议转换在作祟。第三量产阶段一定要做“带宽压力测试”模拟最恶劣的场景比如双摄AI录像显示同时跑连续跑24小时看有没有带宽饥饿导致的偶发卡顿。这种问题在实验室里很难复现但到了用户手里一旦触发就是致命bug。做影像系统带宽管理是“隐形的地基”地基不稳上面盖的楼再漂亮也白搭。希望这篇笔记能帮你在调试的时候少走几个弯路。