Skip to main content
Version: Current

二、核心基础:内存管理

2.1 物理内存布局(DDR 整体划分)

内存分配是应用开发的基础,本章主要介绍 TacoAI 的内存管理机制。

以板载 16GiB DDR 为例,SDK 将总共 16384MiB 地址空间划分成 3 个工作区:

内存区域物理地址范围容量管理方式
Linux 系统内存区0x1,0000,0000 ~ 0x1,FFFF,FFFF4GiB自动管理,不可配置
媒体专用内存区0x2,0000,0000 ~ 0x3,FFFF,FFFF8GiB用户可配置
NPU 专用内存区0x4,0000,0000 ~ 0x4,FFFF,FFFF4GiB用户可配置

各内存区使用逻辑

  • Linux 系统内存区:应用程序运行所需的进程、线程空间、堆空间(heap)都位于此区域
  • 媒体专用内存区:主要用于缓存媒体数据,特指以帧为单位的音视频数据
  • NPU 专用内存区:主要用于加载神经网络模型,以及在执行推理过程中缓存中间数据和推理结果

2.2 内存域模型与访存特性

SDK 在设计上将 DDR 内存按照用途划分为三个域(domain):

系统域(System Domain)

  • 管理方式:由 Ubuntu 系统直接管理
  • 用途:为操作系统本身以及各类应用程序提供运行环境和业务内存
  • 示例:系统调用 malloc() 接口返回的内存即位于系统域

媒体域(Media Domain)

  • 管理方式:由媒体模块(tasys)直接管理
  • 用途:主要用于存储音视频编解码业务所涉及的数据,包括压缩码流数据和解压后的帧数据等

NN 域(Neural Network Domain)

  • 管理方式:由 NPU 驱动直接管理
  • 用途:主要用于存储神经网络(NN)业务所涉及的数据,包括网络模型的指令流和权重数据,以及 NPU 工作时产生的临时数据等

2.2.1 访存特性差异

上述三个域除了名称不同之外,本质差异在于数据的存储方式和访存方式不同:

  • EA65xx 芯片的 CPU 使用虚拟地址访问 DDR,这种虚拟地址与 NPU 硬件使用的虚拟地址不同
  • 两者使用各自独立的内存分配器
  • 虚拟地址在逻辑上是连续的,但是虚拟地址所对应的物理地址一般并不连续,而是以页为单位随机分布在所属的域上
  • 如果数据存储在系统域,则除了 CPU 外其它硬件难以寻址,除非该硬件也支持页表,可以逐页建立地址映射关系

系统域访存特性

  • EA65xx 芯片的 CPU 配备了 MMU(Memory Management Unit)单元
  • 运行在 CPU 上的程序使用虚拟地址访问 DDR 内存(称为 CPU 虚拟地址或系统域虚拟地址)
  • 虚拟地址对应的物理地址以页(每页 4KB)为单位随机分布在系统域上
  • CPU 访问内存需要通过 MMU 做地址映射
  • CPU 以外的主控单元难以访问系统域 buffer 的数据

媒体域访存特性

  • EA65xx 芯片中的媒体单元(包括视频编解码和 JPEG 编解码器)均没有配备 MMU 单元
  • 媒体单元只能通过物理地址访问 DDR 内存,并且要求一帧数据必须是连续存储的(contiguous)
  • SDK 规划了媒体域内存区专门用于存储音视频数据
  • 媒体驱动(tasys)提供了将物理地址映射为 CPU 虚拟地址的接口
  • NPU 驱动提供了将物理地址映射为 NPU 虚拟地址的接口

NN 域访存特性

  • EA65xx 芯片的 NPU 配备了 MMU 单元
  • NPU 硬件使用虚拟地址访问 DDR 内存(称为 NPU 虚拟地址或 NN 域虚拟地址)
  • NPU 虚拟地址与 CPU 虚拟地址无关

2.2.2 数据访问解决方案

如果待推理的图像实际存储在系统域,NPU 不能使用 CPU 虚拟地址进行访问,SDK 支持两种解决方法:

方法一:拷贝方法

  • 实现:在 taRuntime 接口内部将图像数据从系统域复制到 NN 域 buffer
  • 访问方式:NPU 通过 NN 域虚拟地址访问图像
  • 缺点:消耗 CPU 和 DDR 带宽资源
  • 推荐度:不推荐作为正式产品方案

方法二:映射方法

  • 实现:在 taRuntime 接口内部将系统域虚拟地址以内存页为单位逐页映射为 NN 域虚拟地址
  • 缺点:当图像比较大时,操作耗时较多(约 20ms)
  • 推荐度:不推荐作为正式产品方案

推荐方案

根据以上讨论,图像不宜存储在系统域内存区,而应存储在媒体域内存区。taRuntime 接口支持外部提供待推理图像的物理地址,接口内部将物理地址映射为 NN 域虚拟地址,这个操作开销较小。

2.3 tasys 内存介绍

2.3.1 tasys 简介与公共缓存池

  • EA65xx 芯片上的硬件编解码单元和视频处理单元只能使用物理地址访问 DDR
  • 使用 FFmpeg/OpenCV 库提供的硬件加速功能时,相关接口最终只能使用 tasys 模块分配的内存,不能使用 malloc() 接口分配的系统域内存
  • tasys 提供 alloc 接口,以便用户申请连续的物理内存块
  • SDK 中的 tasys 模块提供了配置和创建公共缓存池的接口
  • 用户可以为每个公共缓存池配置一批缓存块(VB,Video Buffer)

⚠️ 注意:

  • 应用程序应在初始化阶段创建好各业务所需的缓存池,业务一旦开始运转,缓存池的配置就不能轻易变化。

2.3.2 tasys 公共缓存池配置

在板端运行时,/boot/firmware/ 目录下存在 taco_sys_memory_config.json 文件,用于配置 common pool 的 tasys 内存。修改 JSON 文件后重启板子生效。

如果想了解 tasys 的具体使用,参考 API 参考的「tasys 接口详解」章节

{
"comm_pool": [
{
"blk_cnt": 24,
"blk_size": 4096,
"meta_size": 0,
"pool_name": "common_pool_0",
"remap_mode": 0,
"zone_name": "anonymous"
},
{
"blk_cnt": 4,
"blk_size": 98304,
"meta_size": 0,
"pool_name": "common_pool_1",
"remap_mode": 0,
"zone_name": "anonymous"
},
{
"blk_cnt": 4,
"blk_size": 196608,
"meta_size": 0,
"pool_name": "common_pool_2",
"remap_mode": 0,
"zone_name": "anonymous"
},
{
"blk_cnt": 4,
"blk_size": 393216,
"meta_size": 0,
"pool_name": "common_pool_3",
"remap_mode": 0,
"zone_name": "anonymous"
},
{
"blk_cnt": 60,
"blk_size": 614400,
"meta_size": 0,
"pool_name": "common_pool_4",
"remap_mode": 0,
"zone_name": "anonymous"
},
{
"blk_cnt": 4,
"blk_size": 786432,
"meta_size": 0,
"pool_name": "common_pool_5",
"remap_mode": 0,
"zone_name": "anonymous"
},
{
"blk_cnt": 256,
"blk_size": 3133440,
"meta_size": 0,
"pool_name": "common_pool_6",
"remap_mode": 0,
"zone_name": "anonymous"
},
{
"blk_cnt": 256,
"blk_size": 3137536,
"meta_size": 0,
"pool_name": "common_pool_7",
"remap_mode": 0,
"zone_name": "anonymous"
},
{
"blk_cnt": 68,
"blk_size": 6266880,
"meta_size": 0,
"pool_name": "common_pool_8",
"remap_mode": 0,
"zone_name": "anonymous"
}
],
"max_pool_cnt": 1024
}

2.4 高性能内存访问策略

2.4.1 缓存一致性问题

典型应用场景

通过 OpenCV 或 TacoCV 接口在图像上绘制图形和文字,这部分功能是 CPU 借助虚拟地址访问 DDR 中的图像数据实现的。

性能优化建议

  • 虚拟地址是否映射为 cacheable 类型对绘图效率影响很大
  • 建议在创建公共缓存池时,将 POOL/VB 的映射类型配置为 CACHEABLE

缓存一致性要求

当 CPU 完成绘图操作后,用户应调用 tasys 模块提供的 taco_sys_cache_flush() 接口将 CPU 缓存中的数据主动同步到 DDR 中,否则 DDR 中的数据可能还是旧的,这就是所谓的 缓存一致性(cache coherency)问题。

2.4.2 关于零拷贝

PC 平台与 EA65xx 平台差异

平台内存使用方式
PC 平台通过 malloc() 从操作系统申请 buffer,加载数据后提交给 FFmpeg 进行编解码
EA65xx 平台由于硬件约束,对 buffer 的使用方式需要变化

硬件访问限制

EA65xx 芯片的硬件单元无法直接访问系统域 buffer,因此:

  • 如果输入数据位于系统域,SDK 必须把数据拷贝到媒体域才能交给硬件处理
  • 这种拷贝会消耗 CPU 和 DDR 资源

零拷贝(Zero Copy)方案

SDK 对 FFmpeg 使用的 AVFrameAVPacket 等结构体进行了扩展:

  • 使用硬件加速功能时,用户可以提供媒体域 buffer 的物理地址以便硬件直接处理
  • 如果用户提供的是系统域 buffer 的虚拟地址,FFmpeg 接口内部会自动申请媒体域 buffer 并执行一次拷贝

性能对比

两种工作方式在以下方面存在区别:

  • DDR 带宽消耗
  • CPU 负载
  • 接口延迟
  • 最高帧率
  • buffer 数量

推荐:建议用户优先采用 零拷贝方式 以获得最佳性能。