1. NPU内存基础认知与优化总览

任务目标

本案例面向RK3588平台NPU开发,目标是建立对NPU内存架构的基础认知,明确后续优化工作的核心方向。完成本案例后,你应能回答:NPU计算时数据存放在哪里、哪些内存区域需要关注、优化的主要手段有哪些。

RK3588 NPU内存架构要点

RK3588集成三核NPU(共6 TOPS算力),其内存使用涉及以下几个关键区域:

  • 系统内存(DDR):输入/输出特征图、权重参数通常驻留于此,通过IOMMU映射供NPU访问。NPU通过AXI总线以高带宽读取,但延迟远高于NPU内部存储。
  • NPU内部SRAM(TCM):容量极小(RK3588 NPU单核TCM约数百KB级别),但带宽极高、延迟极低,用于存放当前计算层的关键中间数据。
  • 权重缓冲区:NPU内部有专用权重缓存,权重数据从DDR预取后在此复用,减少重复DDR访问。

理解上述层次后,优化的本质是:提高数据在NPU内部存储的命中率,减少DDR与NPU之间的低效搬运。

优化目标与方向总览

优化方向针对问题典型手段
内存复用中间特征图占用过大Tensor生命周期分析、内存池复用
数据布局NHWC/NCHW转换开销选择与硬件对齐的layout,避免运行时transpose
零拷贝CPU与NPU间数据往返共享内存、DMA直接搬运、避免memcpy
权重压缩权重DDR带宽瓶颈INT8/INT4量化、权重剪枝后稀疏存储
算子融合多次DDR读写中间结果Conv+ReLU+BN融合为单次NPU执行

内存分配与释放的核心API

在RKNN Toolkit/C API中,内存管理围绕以下关键调用展开,后续案例将反复使用:

// 分配NPU可访问的系统内存(带IOMMU映射)
rknn_tensor_memory *mem = rknn_create_memory(io_attr.size);
// 将内存绑定到输入/输出Tensor
rknn_set_io_mem(ctx, mem, &io_attr);
// 查询Tensor所需内存大小(用于预分配规划)
rknn_query(ctx, RKNN_QUERY_IN_OUT_NUM, &io_num);
// 显式释放
rknn_destroy_memory(mem);

验证路径

本案例为认知型基础,不涉及具体代码运行。验证理解是否到位的方式:

  1. 能画出数据从DDR到NPU计算单元的流向图,标注各环节延迟/带宽差异;
  2. 针对一个典型Conv层,能指出权重、输入、输出分别存放在哪个内存层次;
  3. 能列举至少3种后续案例将使用的优化手段,并说明其减少的是哪一类内存开销。

后续案例衔接

从下一案例开始,将依次深入:内存池复用实现、零拷贝输入输出、layout自动选择、INT8量化对内存带宽的影响、算子融合的内存收益分析。每个案例均提供可编译运行的C代码及RKNN Toolkit调用示例。

系统内存 DDR 输入特征图 NHWC/NCHW 权重参数 原始/量化后 输出特征图 中间/最终结果 IOMMU映射区域 AXI总线 高带宽/高延迟 RK3588 NPU 权重缓冲区 预取后复用 TCM SRAM 中间激活值 MAC 计算阵列 卷积/矩阵运算 激活/池化 逐元素操作 输出写回DDR(低效路径,需优化) 优化核心策略 ① 数据尽量留在TCM/权重缓冲 ② 减少DDR↔NPU搬运次数 ③ 算子融合避免中间结果落DDR ④ 量化压缩DDR传输量

上图展示了RK3588 NPU内存架构的核心数据通路。图中橙色箭头表示输入/权重从DDR载入NPU内部缓冲,红色箭头表示NPU内部数据流动(权重缓冲→计算单元、TCM→计算单元),绿色箭头表示输出写回DDR。优化工作的核心就是减少绿色路径(输出落DDR再读回)和橙色路径(重复从DDR读取相同数据)的出现频率。