存内计算架构将计算操作直接嵌入存储单元内部,从根本上消除冯诺依曼架构中的数据搬运瓶颈。文章讨论基于SRAM、ReRAM和FeFET等不同存储介质的存内计算实现方案,分析其在矩阵乘加运算中的能效优势以及精度和可编程性方面的挑战,为下一代AI计算架构提供技术参考。
需要学习存内计算(Compute-in-Memory),机器人需要端侧AI推理,硬件选型和算力优化是关键。本篇涵盖GPU/TPU/NPU、CUDA、集群调度、算力优化,帮助你理解硬件加速原理。
可视化演示
交互展示冯诺依曼数据搬运瓶颈、CIM交叉阵列MAC运算原理与存内计算能效对比,理解存储计算融合创新。
本节配有交互动效(进入视口后自动加载,约 3KB)。
冯诺依曼数据搬运瓶颈 数据在存储与计算单元间反复搬运 搬运能耗远超计算能耗 E_move >> E_calc 数据搬运成为性能与功耗瓶颈
存内计算架构原理
存内计算(Compute-in-Memory, CIM)是一种颠覆性的计算架构范式,其核心思想是将权重直接存储在存储单元中,计算时输入数据触发存储阵列内的并行乘加(MAC)运算,从根本上消除数据搬运带来的功耗和延迟瓶颈。传统冯·诺依曼架构中,处理器和存储器分离,每次计算都需要将权重从存储器搬运到计算单元,这个搬运过程的功耗往往超过计算本身——据统计,数据搬运能耗占总能耗的60-90%,这就是所谓的“冯·诺依曼瓶颈”。
存内计算的架构将“存储”和“计算”合二为一。存储阵列既是权重的存储介质,又是计算的执行场所。以SRAM阵列为例,权重存储在SRAM单元中,计算时多条字线(Word Line)同时激活,每条字线上的输入电压与存储单元中权重的电导值相乘产生电流,同一位线(Bit Line)上的电流自然汇总完成累加运算。整个过程在模拟域一次性并行完成,无需逐次从存储器读取权重再到计算单元运算。
存内计算的物理基础是欧姆定律和基尔霍夫电流定律。欧姆定律(I = V x G)实现乘法运算:输入电压V乘以存储单元电导G得到电流I;基尔霍夫电流定律实现加法运算:同一位线上多条支路的电流自然汇总。这种利用物理定律直接完成计算的方式,使得一个M行N列的存储阵列可以一次性完成M维输入向量与NxM权重矩阵的乘法运算,并行度极高。
存内计算相比传统数字架构的能效优势来源于三个方面:(1) 消除数据搬运功耗——权重就在计算位置,无需从外部存储器读取;(2) 大规模并行——所有存储单元同时参与计算,而非逐次串行执行;(3) 模拟计算本身功耗低——电流流动的能量消耗远低于数字电路中晶体管频繁翻转的功耗。这三个因素共同使得存内计算的能效比(TOPS/W)可达传统数字芯片的1-2个数量级以上。
SRAM存内计算实现方案
SRAM(静态随机存取存储器)是存内计算中最成熟的实现方案。标准6T SRAM单元由两个交叉耦合的反相器和两个访问晶体管组成,天然支持存储和读取操作。在存内计算模式下,SRAM单元的关键改造是支持多字线同时激活——传统SRAM每次只激活一条字线读取一个存储单元,而存内计算SRAM同时激活多条字线,使得同一列(位线方向)上的多个存储单元同时导通,各自的电流在位线上汇总。
SRAM存内计算的MAC运算流程如下:(1) 权重存储——将量化后的权重值转换为SRAM单元的存储状态(差分对结构用正负电荷表示正负权重);(2) 输入施加——将输入向量的各分量以电压形式施加到对应的字线上;(3) 电流产生——每个SRAM单元根据其存储状态和字线电压产生相应大小的电流;(4) 位线汇总——同一位线上所有单元的电流自然累加,完成乘加运算的加法部分;(5) ADC转换——位线上的模拟电流信号通过ADC转换为数字输出。
SRAM存内计算的关键挑战在于ADC设计。位线上的模拟电流需要高精度、高速度的ADC转换为数字信号。ADC的精度直接决定了计算结果的精度——一个N位ADC提供2^N个量化电平。同时,ADC的功耗和面积在整个存内计算芯片中占有显著比例。常用的ADC架构包括逐次逼近型(SAR ADC)和闪存型(Flash ADC),前者功耗低但速度慢,后者速度快但功耗和面积大。实际设计中需要在精度、速度和功耗之间权衡。
SRAM存内计算的优势在于工艺成熟(与标准CMOS工艺完全兼容)、读写速度快、耐久性近乎无限(无磨损问题)。其局限在于面积效率较低——6T SRAM单元面积较大,限制了阵列密度。典型SRAM存内计算芯片的阵列规模为数百行x数百列,适合中小规模神经网络的推理部署。差分对(Differential Pair)结构是SRAM存内计算中表示正负权重的常用方法:用一对SRAM单元的电导差值表示有符号权重,解决了SRAM只能存储正值的限制。
ReRAM存内计算实现方案
ReRAM(阻变存储器,也称忆阻器Memristor)是存内计算的高密度实现方案。ReRAM单元由金属-绝缘体-金属(MIM)结构组成,通过在外加电压下形成或断裂绝缘层中的导电细丝来切换高阻态(HRS)和低阻态(LRS)。关键特性是电导值可以在高阻态和低阻态之间连续调节,形成多阻态(Multi-Level Cell, MLC),这使得一个ReRAM单元可以存储多位权重信息,大幅提高了存储密度。
ReRAM存内计算的物理原理直接映射神经网络运算。权重映射:将量化后的权重值转换为ReRAM单元的电导值G,权重越大电导越高。乘法运算:根据欧姆定律 I = V x G,输入电压V施加在字线上,ReRAM单元产生与V和G乘积成正比的电流。加法运算:根据基尔霍夫电流定律,同一位线上所有ReRAM单元的电流自然汇总。整个过程在一个时钟周期内并行完成,一个MxN的ReRAM阵列一次性完成M维输入与权重矩阵的乘法。
ReRAM相比SRAM存内计算的核心优势在于:(1) 面积效率极高——1T1R(一个晶体管+一个忆阻器)结构远小于6T SRAM单元,阵列密度可提高5-10倍;(2) 非易失性——断电后权重不丢失,适合always-on推理场景;(3) 多阻态支持——单个单元可存储多位数据,进一步提高等效密度。然而,ReRAM也面临独特挑战:器件一致性较差(工艺偏差大)、耐久性有限(约10^6-10^9次写入)、电导调节范围有限、温度敏感性更强。
ReRAM存内计算的误差来源比SRAM更为复杂:(1) 器件偏差——制造过程中导电细丝形成的随机性导致单元间电导偏差显著;(2) 电导漂移——写入后电导值随时间缓慢漂移;(3) 非线性——电流-电压关系不完全遵循理想欧姆定律,尤其在大电压下出现非线性效应;(4) 噪声——导电细丝的热涨落引入1/f噪声和随机电报噪声(RTN)。这些非理想性要求更精密的校准算法和更鲁棒的量化训练策略。
能效优势与精度挑战
存内计算相比传统数字架构在能效方面具有1-2个数量级的优势。传统数字芯片执行矩阵乘法时,每个权重需要从外部存储器(SRAM缓存或DRAM)读取到计算单元,数据搬运的能耗(约1-100pJ/次)远超计算本身的能耗(约0.01-0.1pJ/次)。存内计算消除了数据搬运,权重就在计算位置,加上模拟并行计算的低功耗特性,整体能效比可达10-1000 TOPS/W,而数字GPU通常在10-50 TOPS/W范围内。
然而,模拟计算天然面临精度挑战。模拟域中的噪声和偏差使得存内计算的精度低于数字计算:(1) 模拟噪声——器件热噪声、1/f噪声、随机电报噪声等引入随机误差;(2) ADC量化误差——模拟电流到数字输出的转换过程引入量化噪声,ADC位数有限(通常6-8位);(3) 器件非理想性——电导偏差、非线性、温度漂移等引入系统性误差。这些误差的累积可能导致推理精度下降2-10%,对于精度敏感的任务(如大语言模型)影响更为显著。
量化感知训练(QAT)是补偿存内计算精度损失的核心技术。QAT在训练的前向传播中插入模拟量化操作(将浮点权重四舍五入到最近的量化电平),同时模拟存内计算的噪声和偏差特性,使模型在训练阶段就“适应”了低精度和模拟误差。反向传播使用直通估计器(Straight-Through Estimator, STE)传递梯度。经过QAT训练的模型部署到存内计算芯片后,精度损失可控制在1-2%以内,远优于直接训练后量化部署(PTQ)的方案。
误差补偿技术是存内计算实用化的另一关键。片上校准(On-chip Calibration)定期测量存储单元的实际电导值并与理想值比对,生成校准系数补偿系统性偏差。权重预失真(Weight Pre-distortion)在写入权重时预先补偿已知的器件非理想性——例如,如果器件存在非线性响应,则预先对权重进行反向非线性变换。输出校正(Output Correction)对推理结果进行后处理修正,使用校准数据集训练一个轻量级校正模型。这些技术的综合应用可以将存内计算的推理精度逼近数字方案。
存内计算AI应用前景
存内计算在边缘AI推理场景中展现出显著的功耗优势。边缘设备(如智能摄像头、可穿戴设备、IoT传感器节点)通常由电池供电,对功耗极为敏感,同时需要持续运行AI推理任务(如目标检测、关键词唤醒、异常监测)。存内计算的毫瓦级甚至微瓦级功耗完美匹配这类场景的需求。例如,基于SRAM的存内计算芯片在关键词唤醒任务中的功耗可低至100微瓦以下,相比数字NPU降低一个数量级,使得设备续航从数天延长到数月甚至数年。
IoT设备部署是存内计算的重要应用方向。海量IoT设备分布广泛、维护困难,对可靠性和长寿命有极高要求。存内计算芯片的非易失性(尤其是ReRAM方案)确保断电后权重不丢失,设备可瞬间恢复推理能力而无需重新加载模型。在工业IoT场景中,存内计算芯片可集成在传感器节点中,实现本地实时数据分析和异常检测,仅将异常事件摘要上传到云端,大幅降低通信带宽和能耗需求。
然而,存内计算在可编程性和训练能力方面仍需突破。当前存内计算芯片主要支持矩阵乘法运算,对于复杂的神经网络算子(如注意力机制、动态路由、自定义激活函数)支持有限。编程模型尚不成熟——开发者需要了解底层硬件特性才能高效部署模型,缺乏像CUDA那样成熟的高层抽象。此外,存内计算无法高效支持训练过程(反向传播需要精确的梯度计算,模拟器件难以满足),模型仍需在数字芯片上训练后再部署到存内计算芯片。
存内计算的未来发展方向包括:(1) 混合信号架构——在模拟存内计算阵列周围集成数字电路,实现模拟MAC和数字非线性操作的混合执行,兼顾能效和精度;(2) 3D堆叠集成——将存内计算阵列与逻辑电路通过TSV(硅通孔)垂直集成,进一步提高带宽密度和能效;(3) 新型存储介质——探索MRAM、PCM等新型存储器的存内计算潜力,在速度、密度、耐久性之间寻找更优平衡。存内计算不会取代数字AI芯片,两者将形成互补的混合计算生态:云端数字芯片负责训练和高精度推理,边缘存内计算芯片负责低功耗推理。
AI 应用场景
边缘智能摄像头低功耗目标检测
阶段:模型部署
解决的问题:电池供电的户外智能摄像头需要持续运行目标检测模型,数字NPU功耗过高导致续航不足,需要在保持检测精度的前提下将推理功耗降低一个数量级
具体案例:某安防公司在户外智能摄像头中部署基于SRAM存内计算芯片的YOLO-tiny目标检测模型。芯片采用64x64 SRAM阵列,INT8量化,集成6位SAR ADC。模型经过量化感知训练(QAT)后部署,权重直接映射到SRAM单元电导值。推理时输入图像特征以电压形式施加到字线,阵列并行完成卷积层的MAC运算,位线电流经ADC转换后输出。实测推理功耗仅2.3mW(数字NPU方案为28mW),精度损失1.2%(mAP从72.3%降至71.4%)。配合3Wh锂电池,摄像头续航从数字方案的12天提升到存内计算方案的5个月,实现真正的always-on AI监控。
工业IoT传感器节点实时异常检测
阶段:推理优化
解决的问题:工厂中部署的数千个振动传感器节点需要本地实时运行异常检测模型,设备维护困难要求芯片具备非易失性和超长寿命,同时功耗必须足够低以支持能量收集供电
具体案例:某石化企业在旋转设备监测项目中部署基于ReRAM存内计算芯片的振动异常检测系统。芯片采用128x128 ReRAM阵列,支持4阻态(每单元2比特),权重非易失性存储。Autoencoder异常检测模型经过QAT训练后部署到ReRAM阵列,利用欧姆定律和基尔霍夫定律直接在阵列中完成矩阵乘法。芯片静态功耗仅15微瓦,推理功耗80微瓦,配合温差能量收集模块(可收集200微瓦)实现完全自供电。片上校准电路每24小时自动校准一次,补偿ReRAM电导漂移。系统运行18个月,检测准确率保持在98.5%以上,成功预警3次轴承早期故障,避免非计划停机损失超500万元。
Python 演示
import numpy as np class SRAMCIMArray: """Simulate SRAM Compute-in-Memory array for matrix-vector multiplication.""" def __init__(self, rows=64, cols=64, adc_bits=8): self.rows = rows self.cols = cols self.adc_bits = adc_bits self.conductance = np.zeros((rows, cols)) self.noise_std = 0.02 # 2% device noise def load_weights(self, weights): """Map quantized weights to SRAM cell conductance values (differential pair).""" w_min, w_max = weights.min(), weights.max() scale = (w_max - w_min) / (2**self.adc_bits - 1) quantized = np.round((weights - w_min) / scale) * scale + w_min # Differential pair: positive conductance for positive weights self.conductance = (quantized - w_min) / (w_max - w_min + 1e-10) self.scale = scale self.w_min = w_min return quantized def analog_mac(self, input_vector): """Perform analog MAC: I = V * G with noise, then ADC quantize.""" # Ideal analog computation ideal_current = input_vector @ self.conductance # Add device noise (thermal + 1/f noise) noise = np.random.normal(0, self.noise_std, self.conductance.shape) noisy_g = self.conductance * (1 + noise) actual_current = input_vector @ noisy_g # ADC quantization i_max = self.cols * 1.0 # max current adc_levels = 2 ** self.adc_bits quantized_current = np.round(actual_current / i_max * adc_levels) / adc_levels * i_max return actual_current, quantized_current, ideal_current class ReRAMCIMArray: """Simulate ReRAM Compute-in-Memory array with memristor non-idealities.""" def __init__(self, rows=128, cols=128, states=16): self.rows = rows self.cols = cols self.states = states # number of conductance levels (MLC) self.conductance = np.zeros((rows, cols)) self.device_variation = 0.05 # 5% process variation self.drift_rate = 0.001 # conductance drift per hour def load_weights(self, weights): """Map weights to ReRAM conductance levels with MLC quantization.""" w_min, w_max = weights.min(), weights.max() levels = np.linspace(w_min, w_max, self.states) # Quantize to nearest conductance level indices = np.argmin(np.abs(weights[..., np.newaxis] - levels), axis=-1) quantized = levels[indices] self.conductance = (quantized - w_min) / (w_max - w_min + 1e-10) self.levels = levels self.w_min = w_min self.w_max = w_max return quantized def analog_mac(self, input_vector, hours_since_write=0): """ReRAM MAC with Ohm's law + Kirchhoff's law + non-idealities.""" # Process variation variation = np.random.normal(0, self.device_variation, self.conductance.shape) varied_g = self.conductance * (1 + variation) # Conductance drift over time drifted_g = varied_g * (1 - self.drift_rate * hours_since_write) drifted_g = np.clip(drifted_g, 0, 1) # Ohm's law: I = V * G, Kirchhoff: sum currents on bitline output = input_vector @ drifted_g return output # Demonstrationprint("=== SRAM CIM Array Demo ===")np.random.seed(42)sram = SRAMCIMArray(rows=8, cols=8, adc_bits=8)weights = np.random.randn(8, 8).astype(np.float32)sram.load_weights(weights)inp = np.array([0.5, -0.3, 0.8, -0.1, 0.6, -0.4, 0.2, -0.7])actual, adc_out, ideal = sram.analog_mac(inp)print(f"Ideal output: {ideal[:4]}")print(f"Analog output: {actual[:4]}")print(f"ADC output: {adc_out[:4]}")print(f"Mean abs error: {np.abs(actual - ideal).mean():.6f}") print("\n=== ReRAM CIM Array Demo ===")reram = ReRAMCIMArray(rows=8, cols=8, states=16)reram.load_weights(weights)out_fresh = reram.analog_mac(inp, hours_since_write=0)out_drifted = reram.analog_mac(inp, hours_since_write=1000)print(f"Fresh output: {out_fresh[:4]}")print(f"Drifted (1000h): {out_drifted[:4]}")print(f"Drift error: {np.abs(out_fresh - out_drifted).mean():.6f}")
class SRAMCIMArray:SRAM存内计算阵列模拟器,模拟6T SRAM单元阵列的并行MAC运算过程def load_weights(self, weights):将量化后的权重映射到SRAM单元的电导值,使用差分对结构表示正负权重noise = np.random.normal(0, self.noise_std, self.conductance.shape)模拟SRAM器件噪声:热噪声和1/f噪声导致电导值随机波动quantized_current = np.round(actual_current / i_max * adc_levels) / adc_levels * i_maxADC量化:将模拟电流离散化为2^N个电平,ADC位数决定计算精度上限class ReRAMCIMArray:ReRAM存内计算阵列模拟器,包含忆阻器特有的多阻态、工艺偏差和电导漂移indices = np.argmin(np.abs(weights[..., np.newaxis] - levels), axis=-1)ReRAM多阻态量化:将权重映射到最近的可区分电导电平(MLC模式)drifted_g = varied_g * (1 - self.drift_rate * hours_since_write)ReRAM电导漂移模型:写入后电导值随时间缓慢漂移,是ReRAM存内计算的主要误差源output = input_vector @ drifted_g欧姆定律乘法+基尔霍夫累加:输入电压乘电导产生电流,位线汇总完成矩阵向量乘法
常见问答
存内计算的核心思想是什么?它解决了传统架构的什么问题?
SRAM存内计算是如何实现矩阵乘法的?
ReRAM存内计算相比SRAM有什么优势和劣势?
存内计算面临的主要精度挑战有哪些?如何解决?
存内计算在AI领域的应用前景如何?有哪些局限性?
常见误区
误区存内计算就是近存计算(Near-Memory Computing)
正解存内计算(CIM)和近存计算(NMC)是两个不同的概念。近存计算将计算单元放置在存储器附近以减少数据搬运距离,但计算和存储仍然是物理分离的。存内计算则直接利用存储单元的物理特性在存储阵列内部完成计算,计算和存储共享同一物理介质。存内计算的消除数据搬运程度更彻底,能效优势更显著,但设计复杂度也更高。
为何常见:两者都旨在减少数据搬运开销,名称相似,容易混淆。实际上近存计算是存内计算的“温和版本”,降低了对模拟电路设计的要求但能效收益也较小。
误区存内计算可以完全取代GPU进行AI训练和推理
正解存内计算无法取代GPU。存内计算主要支持矩阵乘法运算,且模拟精度有限(INT6-INT8),无法高效执行训练所需的反向传播和梯度更新。复杂算子(如注意力机制、LayerNorm)需要ADC转数字后计算再转回模拟,开销大。存内计算的定位是边缘低功耗推理加速器,与云端GPU/NPU形成互补关系,而非替代。
为何常见:存内计算的能效优势令人印象深刻,容易误以为它是通用解决方案。实际上它只适用于特定场景(低功耗边缘推理),训练和高精度推理仍需数字芯片。
误区SRAM存内计算和ReRAM存内计算的精度差不多
正解两者精度特性差异显著。SRAM工艺成熟、一致性好、噪声较低,但面积密度低;ReRAM密度高但器件一致性差、电导漂移严重、噪声更大。在相同量化位数下,SRAM存内计算的推理精度通常比ReRAM高1-3个百分点。但ReRAM通过多阻态技术和更精密的校准算法可以缩小差距。选择哪种方案取决于应用场景对精度、面积和功耗的不同需求。
为何常见:两者都是存内计算方案,容易笼统地认为它们的精度水平相近。实际上不同存储介质的物理特性差异导致精度表现不同。
误区存内计算不需要量化,模拟计算天然支持高精度
正解恰恰相反,存内计算必须依赖量化技术。模拟计算的精度受限于器件噪声、ADC位数和电导分辨能力,天然无法达到FP32精度。实际存内计算芯片通常使用INT6-INT8量化,需要通过量化感知训练(QAT)使模型适应低精度表示。不做量化的“全精度”模拟计算反而会因为噪声和偏差导致更大的精度损失。量化是存内计算实用化的必要前提,而非可选优化。
为何常见:“模拟”给人连续、高精度的印象,但实际上模拟电路的精度受限于物理器件的非理想性,远不如数字电路的确定性精度。
误区存内计算芯片部署后无需维护,一次写入永久使用
正解存内计算芯片需要定期校准和维护。SRAM方案虽然耐久性近乎无限,但仍受温度漂移影响,需要温度补偿。ReRAM方案的电导值会随时间漂移(每小时约0.1%),器件老化也会改变电导特性。实际部署中需要片上校准电路定期(如每24小时)自动校准,补偿电导漂移和老化效应。在极端温度场景下,还需要实时温度补偿。忽视维护将导致推理精度随时间持续下降。
为何常见:数字芯片的“一次编程永久使用”特性让人误以为存内计算芯片也无需维护。实际上模拟器件的物理特性会随时间和环境变化,需要持续校准。
参考来源
- paperCompute-in-Memory: Architecture and CircuitsIEEE综述论文,全面介绍存内计算的架构原理、SRAM和ReRAM实现方案、电路设计挑战和性能评估
- paperA Survey of ReRAM-Based In-Memory Computing for AI ApplicationsNature Electronics发表的ReRAM存内计算综述,详细讲解忆阻器物理机制、阵列设计和AI推理部署实践
- paperSRAM-Based Compute-in-Memory Design for Edge AISRAM存内计算设计方法论论文,涵盖差分对结构、ADC设计、量化映射和边缘AI部署案例
- paperQuantization-Aware Training for Analog In-Memory Computing面向模拟存内计算的量化感知训练方法论文,讲解如何通过QAT补偿模拟计算精度损失
- paperIn-Memory Computing for Artificial Intelligence: From Devices to SystemsScience期刊发表的存内计算系统级综述,从器件到系统全面分析CIM技术在AI中的应用前景和挑战