NPU地址映射为何抖?TLB先看
现场有些慢帧既不是模型变重,也不是带宽不够,而是访问同样的数据时忽快忽慢。NPU碰到这类抖动,往往要先把目光从算子移开,去看地址翻译链路里的 IOMMU 映射和 TLB 命中到底稳不稳。
地址翻译不是免费的中间层。加速器访问主存前,通常要先经过页表映射和权限检查;若缓冲区由很多零散小页拼成,前端就得频繁查询翻译结果。TLB 一旦装不下活跃工作集,访问会不断触发回填,数据尚未真正进入阵列,时间已经花在找地址上。平均带宽统计常常看不出这种问题,因为瓶颈并不在总线峰值,而在每次访问前的停顿。
页大小混用会让停顿更难预测。输入帧可能来自 4K 小页,权重区却映射成大页,中间激活再落在另一个分配器管理的碎页池里。只要这些区域在执行窗口里交替访问,TLB 内容就会被不同粒度条目反复挤占。某些模型在短跑测试里没事,长时间运行后才变慢,就是因为碎页逐渐增多,命中率一点点被拖下去了。
离散分配对 DMA 也不友好。硬件虽然能按照 scatter-gather 链表搬运数据,但链越长,描述符解析和地址切换越频繁;若某些页还跨越对齐边界,主存控制器的突发效率也会跟着下降。此时表面上看是访存延迟升高,根源却是“同一块逻辑缓冲被分配得太碎”,导致每一层都在为地址跳转付税。
IOMMU 映射开销还和生命周期管理相关。频繁创建和销毁临时缓冲,会逼着驱动不断建立、撤销或刷新映射;若运行时没有复用稳定地址区,图执行每轮都可能重新走一遍映射路径。对短帧实时任务来说,这种管理动作的抖动比绝对耗时更麻烦,因为它会直接拉宽尾延迟。
更稳妥的做法,是给高频缓冲预留长生命周期的大页区,把输入、激活和输出按角色分仓,减少跨区域交替访问。权重和常驻工作区尽量保持固定物理布局,临时对象也优先从受控池中重复利用,而不是每轮都向通用分配器伸手。这样做不是为了省几次映射,而是为了让地址翻译工作集保持稳定。
大页也不是越大越好,若少数短命对象被硬塞进大页池,回收和复用粒度都会变粗,最终又会把本该稳定的工作集重新打散。
对长期在线节点,还应定期检查页池碎化趋势,因为地址布局一旦缓慢劣化,短测阶段正常的工作集命中率也会在数周后滑出甜点区。
一旦驱动开始为了找连续页而反复重试分配,慢帧就会比计数器报警更早出现。
定位这类问题时,应同时采集 TLB 未命中、映射刷新次数、scatter-gather 段数和慢帧对应的缓冲来源。若性能下降总伴随页段数增多,就说明问题更像碎页;若一遇到特定模型切换就抖,则可能是多工作集交替把翻译缓存打爆。没有这些观测点,团队往往会误把地址问题当成带宽或算力问题。
地址翻译层看似离算法很远,实际却能决定实时性是否稳定。只要页布局和翻译命中先被管住,NPU的主存访问就不会被隐蔽的地址抖动拖成时快时慢。





