2、硬件基础:认识典型MCU的Flash、SRAM和CPU周期特性,理解存储层次与功耗的基本原理

TinyML模型最终要部署在MCU(微控制器)上运行,而MCU的资源与PC或手机上的CPU截然不同。理解Flash、SRAM和CPU周期这三者的物理特性与功耗关系,是进行模型裁剪、量化、算子优化和内存规划的前提。本章将围绕典型ARM Cortex-M系列MCU,拆解存储层次、访问能耗差异以及周期数对功耗的直接影响,帮助你在算法设计与硬件约束之间建立量化直觉。

存储层次 Flash(非易失) 容量:256KB ~ 2MB 存放模型权重 + 代码 读能耗:~100 pJ/bit SRAM(易失) 容量:32KB ~ 512KB 存放激活值 + 中间变量 读能耗:~50 pJ/bit 寄存器堆 容量:几十B 读能耗:~5 pJ/bit CPU执行单元 Cortex-M4/M33 主频:48 ~ 240 MHz 周期数 = 功耗时间基准 功耗公式 P = C × V² × f 动态功耗 ∝ 周期数 关键路径 Flash读取 → 指令/权重 SRAM读写 → 激活值 ALU计算 → MAC操作 能耗对比(相对值) Flash读 100 SRAM读 50 MAC运算 25 寄存器访问 5 核心结论 1. Flash读取最昂贵 2. 减少Flash访问 = 降功耗 3. 权重驻留SRAM可节能 4. 周期数直接决定能耗

2.1 典型MCU的存储资源:Flash与SRAM的容量与角色

在TinyML部署中,MCU的存储资源决定了模型能否被装载以及运行时数据如何流转。以STM32L4系列(Cortex-M4F)和nRF5340(双核Cortex-M33)为例,它们代表了当前TinyML主流的硬件基线。Flash用于存储神经网络的权重、偏置、量化参数以及推理代码本身;SRAM则用于存放输入特征图、中间激活值、输出缓冲区和运行时堆栈。由于Flash是非易失的,掉电后数据不丢失,因此模型权重通常固化在Flash中;而SRAM每次上电需要重新初始化,但其读写速度远快于Flash。

一个典型的TinyML场景:部署一个MobileNetV2(1.0, 224x224)模型,其权重约13.5MB,远超普通MCU的Flash容量。因此实际部署时往往需要经过量化(如int8)和剪枝,将模型压缩到几百KB甚至几十KB。例如,将权重从float32量化为int8后,体积缩小4倍;若进一步使用深度可分离卷积和知识蒸馏,模型可压缩至200KB以内,从而适配具有256KB Flash的MCU。SRAM方面,推理时的峰值激活值通常为权重体积的1/3到1/2,因此需要预留足够空间避免内存溢出。

存储资源规划要点:
  • Flash容量:决定模型权重上限。若模型超过Flash容量,需考虑外部SPI Flash,但会显著增加读取延迟和功耗。
  • SRAM容量:决定推理时的中间数据缓冲。激活值过大时需采用“内存复用”策略,即同一块SRAM在不同层之间交替使用。
  • Flash与SRAM的访问速度差异:Flash通常需要等待状态(wait states),而SRAM可零等待访问。这意味着频繁读取Flash中的权重会拖慢CPU执行速度。

2.2 CPU周期特性:主频、流水线与指令周期

MCU的CPU周期是衡量执行时间的基本单位。Cortex-M4和M33内核采用三级流水线(取指、解码、执行),大多数单周期指令(如加法、移位)在一个时钟周期内完成,而乘法指令(MUL)需要1-3个周期,浮点运算(FPU)则可能需要14个周期以上。对于TinyML推理,最核心的操作是乘加运算(MAC),即一次乘法和一次加法。在Cortex-M4上,如果使用DSP指令(如SMLAD),可以在单周期内完成一个16位乘加;但若使用浮点运算,则每个MAC需要多个周期,导致推理时间成倍增加。

主频直接决定了每秒可执行的周期数。例如,一个运行在80MHz的MCU,每秒有80M个周期。若一次推理需要10M个周期,则推理时间为125ms。功耗方面,动态功耗公式为:

P_dynamic = α × C_load × V² × f

其中α为翻转率(即每个周期内信号翻转的比例),C_load为负载电容,V为供电电压,f为时钟频率。降低主频f可以线性降低功耗,但会延长推理时间;降低电压V则功耗呈平方级下降,但MCU通常有最低工作电压限制。因此,在TinyML中,减少周期数是降低功耗的最有效手段——周期数减少意味着完成推理所需的时间缩短,同时动态功耗也成比例下降。

操作类型 指令示例 周期数(Cortex-M4) 相对能耗
寄存器加法 ADD R0, R1, R2 1 1x
SRAM读取 LDR R0, [R1] 2(零等待) ~10x
Flash读取 LDR R0, [R1](Flash地址) 2-4(含等待状态) ~20x
16位乘加 SMLAD 1 ~5x
浮点乘加 VFMA 3-14 ~30x

2.3 存储层次与功耗:为什么Flash读取是“能耗大户”

从能耗角度看,不同存储介质的单位比特读取能耗差异巨大。Flash的读取需要电荷泵升压和灵敏放大器,其单位比特能耗约为SRAM的2倍,是寄存器访问的20倍。在TinyML推理中,权重数据需要反复从Flash读取。以一次卷积层计算为例,假设权重为3x3x64x128,即约73,728个权重值,每个权重为int8(8位),则每次卷积操作需要从Flash读取约73KB数据。若整个模型有10个这样的卷积层,则Flash读取总量约为730KB。相比之下,SRAM中的激活值虽然也频繁读写,但其能耗仅为Flash的一半。

因此,一个重要的优化策略是权重缓存:将当前层权重从Flash加载到SRAM中,然后反复使用。这类似于CPU的Cache机制,但由程序员手动管理。例如,在STM32上使用DMA将Flash中的权重批量搬运到SRAM,再执行卷积运算,可减少Flash访问次数。另一种策略是权重重排,将权重按通道或按行排列,使得读取时能连续访问Flash,减少地址切换带来的额外周期。

经验法则:在TinyML中,Flash读取的能耗通常占推理总能耗的40%-60%。如果发现模型推理时功耗过高,优先检查Flash读取次数是否过多,而不是盲目降低主频。

2.4 案例拆解:STM32L4上部署int8模型的内存与功耗分析

我们以一个实际案例来串联上述概念。假设在STM32L476(Cortex-M4F,80MHz,1MB Flash,128KB SRAM)上部署一个关键词唤醒模型(KWS),模型结构为:2个卷积层 + 1个全连接层,int8量化后总权重为180KB,激活值峰值为32KB。

初始现象:模型推理时间为45ms,平均电流为12mA(3.3V供电),功耗约39.6mW。电池容量为200mAh,理论续航约16.7小时,但实际产品要求续航超过24小时。

分析过程:通过性能分析器(如STM32CubeMonitor)发现,CPU执行周期数为3.6M,其中约2.1M周期用于Flash读取等待,占比58%。进一步分析,Flash读取的数据量为:每层卷积权重读取约90KB,两层共180KB,加上代码读取约50KB,总计230KB。每次Flash读取(32位)需要2个等待周期,导致大量CPU空转。

优化操作:

  1. 权重驻留SRAM:将第一层卷积权重(80KB)预加载到SRAM中,推理时直接从SRAM读取。由于SRAM零等待,Flash读取等待周期减少约40%。
  2. DMA批量搬运:使用DMA在后台将第二层权重从Flash搬运到SRAM,与第一层计算重叠,隐藏Flash读取延迟。
  3. 降低主频至64MHz:由于Flash等待周期减少,CPU利用率提高,主频降低后仍能在45ms内完成推理,但动态功耗降低约20%。

结果对比:优化后推理时间降至38ms,平均电流降至8.5mA,功耗约28mW,续航提升至23.5小时。代价是SRAM占用从32KB增至112KB(接近128KB上限),需要谨慎管理内存分配。

复盘经验:Flash读取等待是MCU推理的主要瓶颈之一。通过“空间换时间”的SRAM缓存策略,能有效减少CPU空转周期,从而降低总功耗。但SRAM资源有限,需要权衡缓存层数与内存占用。

常见误区:不要认为降低主频就能线性降低功耗。如果主频降低导致推理时间延长,系统可能进入更长的活跃状态,反而增加总能耗。正确的做法是先减少周期数(优化算法和内存访问),再考虑降频。

2.5 存储层次与功耗的工程实践要点

在实际TinyML项目中,理解存储层次与功耗的关系需要落实到具体操作中。以下是几条可执行的建议:

  • 使用内存映射文件:将模型权重定义为const数组,链接到Flash地址,利用MCU的指令Cache(如果有)加速重复读取。
  • 分析链接映射文件:检查.map文件,确认权重和代码在Flash中的布局,避免跨页边界导致额外等待周期。
  • 利用低功耗模式:在推理间隙进入Sleep模式,但需注意唤醒延迟与SRAM保持功耗的平衡。
  • 选择合适的数据类型:int8比float32不仅体积小4倍,且Flash读取次数减少4倍,能耗显著降低。

此外,不同MCU厂商的Flash加速器(如STM32的ART Accelerator、NXP的FlexSPI)会影响实际读取性能。在选型时,应关注Flash的零等待状态访问频率范围,以及是否有指令Cache和数据Cache。例如,STM32L4的ART加速器允许在最高主频下实现Flash零等待执行,但仅对顺序代码有效;若代码有大量跳转,则Cache命中率下降,等待周期增加。

总结:Flash、SRAM和CPU周期三者共同决定了TinyML推理的功耗。Flash读取是最大的能耗来源,SRAM是降低Flash访问的关键缓冲,而CPU周期数则是衡量所有优化效果的最终指标。在后续章节中,我们将基于这些硬件特性,讨论模型量化、算子优化和内存规划的具体方法。