Arm Ethos-U NPU架构概览:核心架构、计算单元、内存层次与CPU协同
在嵌入式AI推理场景中,延迟预算的精确控制始于对硬件执行模型的深刻理解。Arm Ethos-U系列NPU(神经网络处理单元)并非通用处理器,而是一个高度特化的、面向CNN和Transformer等深度学习工作负载的可配置加速器。本章将拆解其核心架构、计算单元、内存层次以及与CPU的协同机制,帮助开发者建立从“算子映射”到“硬件行为”的完整认知,为后续延迟预算建模和推理优化奠定基础。
上图展示了Ethos-U NPU的系统级架构。从延迟预算控制的角度,需要重点关注三个核心要素:计算单元的数据吞吐能力、内存层次间的数据搬运开销以及CPU与NPU之间的同步机制。下面逐一展开。
2.1 核心架构:从命令流到数据流的映射
核心原理:Ethos-U NPU采用可配置的脉动阵列(Systolic Array)作为主计算引擎,而非传统的SIMD或VLIW架构。这意味着卷积运算被硬件化为“数据在阵列中逐周期流动、权重保持静止”的模式。NPU内部的控制单元(Control Unit)负责解析CPU下发的命令描述符(Command Descriptor),将其转换为对MAC阵列、DMA引擎和激活单元的具体控制时序。
与GPU或DSP不同,Ethos-U没有复杂的指令流水线,也没有分支预测。它的执行模型是“命令-执行-完成”的简单状态机。每个推理任务被分解为一系列命令,包括:加载权重、加载输入、执行卷积/全连接、执行激活/池化、存储输出。这种设计使得硬件开销极低,但也意味着命令下发效率和命令间的依赖关系直接影响延迟。
| 架构组件 | 功能说明 | 对延迟的影响 |
|---|---|---|
| 控制单元 | 解析命令描述符,生成内部时序控制信号 | 命令队列深度不足时,CPU需等待NPU空闲 |
| MAC阵列 | 执行卷积/矩阵乘法的乘累加运算 | 阵列尺寸决定峰值算力,利用率决定实际吞吐 |
| 激活/池化单元 | 硬件实现ReLU、Softmax、最大/平均池化 | 避免中间结果写回内存,减少一次DMA往返 |
| 累加器缓冲 | 暂存部分和(Partial Sum),支持大通道数卷积 | 缓冲不足时需拆分通道,增加计算轮次 |
2.2 计算单元:MAC阵列与数据复用策略
核心原理:Ethos-U的MAC阵列采用权重静止(Weight Stationary)的数据流。即权重从SRAM加载到阵列后保持不动,输入特征图数据在阵列中逐行流动,每个周期每个MAC单元完成一次乘累加。这种设计最大化了权重的数据复用率,减少了从SRAM读取权重的次数。
判断方法:计算MAC阵列的理论利用率时,需要关注两个参数:阵列尺寸(如8x8=64个MAC,或16x16=256个MAC)和数据位宽(INT8、INT16或FP16)。实际利用率取决于卷积层的通道数、卷积核尺寸和输入分辨率是否与阵列尺寸匹配。例如,当输入通道数为3(RGB图像)时,第一个卷积层可能无法完全填满16x16的阵列,导致利用率下降。
// 理论计算时间估算示例(伪代码)
// 假设: 16x16 MAC阵列, 256 MACs, 1GHz时钟
// 卷积层: 3x3x64x64, 输入特征图 112x112x64
total_macs = 3 * 3 * 64 * 64 * 112 * 112; // 约 1.85G MACs
cycles = total_macs / 256; // 约 7.2M cycles
time_ms = cycles / 1e9 * 1000; // 约 7.2ms(纯计算时间)
// 实际延迟还需加上权重加载、输入DMA、输出DMA时间
案例拆解:假设在Cortex-M55 + Ethos-U55(256 MACs)平台上运行一个简单的二值分类模型(输入32x32x3,两层卷积+全连接)。初始实现中,开发者将整个模型权重放在外部DDR中,每次推理时NPU通过DMA从DDR加载权重。实测延迟为8.5ms,而理论计算时间仅为0.4ms。通过分析发现,权重加载时间占6.8ms,原因是DDR带宽仅为400MB/s,而模型权重为2.8MB。优化方案:将权重预加载到NPU本地SRAM(512KB),并采用权重压缩(INT8量化+稀疏化),最终权重降至1.1MB,延迟降至2.1ms。
2.3 内存层次:SRAM、DDR与DMA的延迟博弈
核心原理:Ethos-U的内存层次分为三级:寄存器/累加器缓冲(最内层,周期级访问)、NPU本地SRAM(纳秒级访问,容量128KB-1MB)、系统内存(DDR或外部SRAM)(百纳秒级访问,容量大)。NPU通过多个DMA引擎在SRAM和系统内存之间搬运数据。延迟预算控制的核心在于最大化SRAM命中率,避免NPU等待DMA传输完成。
操作流程:在Vela编译器(Arm官方NPU编译器)中,内存规划遵循以下步骤:
- 分析模型图:识别所有张量的生命周期和依赖关系。
- SRAM分配:将权重和中间特征图尽可能放入SRAM,优先分配生命周期短且占用大的张量。
- DMA调度:将DMA传输与计算重叠(Double Buffering),即当前层计算时,预取下一层的权重和输入。
- 溢出处理:当SRAM不足时,将部分张量溢出到DDR,并插入同步屏障。
| 内存层级 | 典型容量 | 访问延迟 | 带宽 | 延迟控制策略 |
|---|---|---|---|---|
| 累加器缓冲 | 几KB | 1-2 cycles | 极高(阵列直连) | 减少部分和写回SRAM的次数 |
| NPU本地SRAM | 128KB - 1MB | 2-5 ns | 128-bit @ 1GHz | 权重常驻,双缓冲DMA |
| 系统DDR | 16MB - 2GB | 50-100 ns | 32-bit @ 400MHz | 批量传输,避免随机访问 |
2.4 与CPU的协同工作:命令下发与同步机制
核心原理:CPU与NPU通过共享内存的命令队列进行异步通信。CPU将命令描述符写入约定的内存区域,然后写NPU的控制寄存器(如BASE寄存器)触发NPU开始执行。NPU执行完毕后,通过中断或轮询状态寄存器通知CPU。这种设计允许CPU在NPU计算的同时执行其他任务(如音频采集、传感器读取),实现流水线并行。
判断方法:评估协同效率时,需要关注三个指标:命令下发延迟(CPU写命令到NPU开始执行的时间)、NPU计算时间、CPU回收结果时间。理想情况下,三者应完全重叠。实际中,常见瓶颈是CPU在等待NPU中断时进入低功耗模式,导致唤醒延迟(几十微秒)。
// CPU侧命令下发示例(C语言伪代码)
volatile uint32_t *cmd_queue = (uint32_t *)0x30000000; // 命令队列基地址
volatile uint32_t *npu_base = (uint32_t *)0x40000000; // NPU控制寄存器
// 1. 填充命令描述符
cmd_queue[0] = CMD_LOAD_WEIGHT | (weight_addr & 0xFFFF);
cmd_queue[1] = CMD_LOAD_INPUT | (input_addr & 0xFFFF);
cmd_queue[2] = CMD_CONV | (conv_params);
cmd_queue[3] = CMD_STORE_OUTPUT | (output_addr & 0xFFFF);
// 2. 触发NPU执行
*npu_base = (uint32_t)cmd_queue; // 写入命令队列指针
// 3. 等待完成(轮询或中断)
while (!(*npu_base & NPU_STATUS_DONE)) {
__WFE(); // 等待事件,降低功耗
}
案例拆解:在智能门锁的人脸识别场景中,系统需要每200ms执行一次人脸检测(NPU任务)和一次特征比对(CPU任务)。初始实现中,CPU在NPU执行期间进入睡眠,NPU完成后通过中断唤醒CPU。实测发现,中断唤醒延迟约80μs,导致整体周期从200ms增加到200.5ms,虽然看似微小,但在连续抓拍场景下会累积。优化方案:采用轮询+超时机制,CPU在NPU执行期间执行轻量级任务(如检查传感器状态),并设置1ms超时轮询NPU状态寄存器。优化后,唤醒延迟降至5μs以下,且CPU利用率仅增加3%。
2.5 架构特性对延迟预算的约束总结
基于上述架构分析,延迟预算控制需要遵循以下原则:
- 计算与搬运重叠:利用双缓冲机制,确保DMA传输与MAC计算并行,隐藏数据搬运延迟。
- SRAM容量规划:优先将高频访问的权重和中间特征图放入SRAM,避免DDR访问。
- 命令批量下发:将多个层的命令合并为一次下发,减少CPU与NPU的同步次数。
- 量化与压缩:INT8量化可减少50%的DMA带宽需求,稀疏化可进一步减少权重加载量。
- CPU任务裁剪:将可并行的CPU任务(如预处理)与NPU计算重叠,避免串行等待。