近年来,随着多核处理器的发展和各类领域定制加速器的不断涌现,计算系统的计算性能得到了迅速提高。但是,存储架构受到传统存储器件(SRAM/DRAM)密度和带宽的限制,已经逐渐成为计算系统发展的瓶颈。另外,数据密集型应用中包含数据量的爆炸式增长,也进一步加剧了这一问题。例如神经网络、图计算等应用,不仅参数量巨大,而且数据的局部性很差,导致处理器和主存之间需要频繁地进行数据交互,不仅会拖慢整个系统的运行速度,并且还会造成巨大的能量开销(比如,将两个浮点数由主存传送至CPU寄存器的能耗,和使用这两个浮点数进行一次运算的能耗相比,可以高出1~2个数量级)。以上便是传统计算机体系结构中著名的存储墙问题,而如何打破存储墙,已经成为当前体系结构领域的一个非常重要的研究课题。

存内计算(Processing In Memory,PIM)架构是有潜力打破存储墙的设计方法之一。它通过赋予主存架构一定的计算能力,可以显著减少处理器与主存之间的数据传输过程,因此有希望从根本上解决存储墙问题。存内计算架构有很多种具体的实现方式,既可以基于传统的NANDFlash、DRAM、SRAM等存储工艺实现,也可以利用新型的非易失存储器件(ReRAM、MRAM、PCM等)来实现;既可以采用数字逻辑的处理模式,也可以采用模拟运算的方式进行处理;既可以利用3D堆叠或者在存储阵列内部实现(NearDataProcessing,NDP),也可以利用器件级别的特性实现真正阵列内部的细粒度存算融合。虽然新型存储器件为存算一体的发展带来了新的 机遇,但这些器件目前存在的缺陷也带来了许多挑战。

快速计算结存(存内计算的挑战与解决思路探讨)(1)

模拟计算的误差

第一个重要的挑战是,模拟计算本身是存在误差的。无论是新型存储器件本身的电导值无法精确写入,还是运行时受到各种噪声的影响,都可能会导致结果出现偏差。例如,之前的工作[5]指出,这些误差会导致仅仅靠硬件实现神经网络计算非常困难,作者在克服种种阻碍后用8个2048个cell的交叉阵列实现了一个五层的CNN来处理MNIST数据集。下面是对典型误差来源及其解决思路的简单介绍:

1.写入误差。以ReRAM为例,改变其电导值是通过施加电压进行的,但无法精确控制电压脉冲的强度对电导改变的影响。常见的解决方式叫做“programming-and-verify”,即每次加电压后都读取一次ReRAM的电导值,根据其偏离目标值的情况施加一个更精细的电压进行微调,如此重复若干次。但由于电压的精度有限,每次读出电导值同样存在误差,这种方法只能尽量减少写入误差的影响,并不能完全消除写入误差。此外,这种方式显著增加了写操作的开销,并加剧了读写不对称现象。

2.Stuck-At-Fault(SAF)。SAF是指一些cell保持在高阻态或低阻态,不能被改动。存储芯片在出厂时便会有一部分cell处于SAF状态,之后有一些cell在使用过程中也可能进入该状态。若想从根本上解决该问题,需要依赖工艺的进步带来良率的提升。目前缓解该问题的方法有:通过在训练神经网络时添加将要使用的器件实测的SAF的信息,使得神经网络在训练时就能学到相关的信息;根据实测的SAF的情况增加补偿电路,用来补偿SAF造成的误差。

3.电压降(IR-Drop)。电压降是指由于导线本身的电阻值产生的分压,会造成实际加在cell上的电压比期望值要低。解决该问题主要有两种思路:第一种是减小交叉阵列的规模,这样不会有离电压源过远的cell,因为cell被过长的导线分压会很严重。很多之前的工作表明,128×128或更小的交叉阵列在针对简单数据集(例如MNIST、Cifar10)的网络上,IR-Drop造成的影响基本可以忽略。更复杂的任务可能需要进一步降低交叉阵列的规模。第二种思路也是在训练神经网络时考虑IR-Drop的影响,使神经网络学到其相关信息并适应其影响。

4.热噪声、随机电报噪声等。这些噪声都是使用ReRAM等新型存储器件时,可能短暂地造成其电导值变化的噪声。它们的特点是随时间变化,总体上造成的误差呈正态分布。以往的工作尝试在训练神经网络时考虑这些噪声来减少它们的影响,但效果不佳。由于这些噪声在高阻时影响更为显著,限制了研究人员将新器件的阻值做得更高来减少能耗。现阶段减少这些噪声影响的主要的方法是减小每个cell表示的比特数,以及减小交叉阵列的规模。但这些方法都会影响到性能和效率。

除了针对以上各种误差“对症下药”以外,另一种思路则是在误差发生后进行检错或纠错。如果采用检错的方式,则需要在检测到错误时重新计算一遍,这种方法主要对热噪声等随时间变化的噪声比较有效。若采用纠错的方式,则可以在检测到错误时直接纠正,但纠错的编码往往比检错的编码更加复杂。无论是纠错码还是检错码,一般都是对写入交叉阵列的权重矩阵进行编码。它们都需要满足对乘累加同态的基本性质,即在编码后仍能够进行乘法运算和加法运算,解码后的结果等于编码前直接进行对应运算的结果。例如,“乘3”就是一种典型的检错码。通过将所有权重全部乘3,如果乘累加的结果不是3的倍数,就可以断定计算发生了错误。

读写不对称

ReRAM等新型存储器件往往有读写不对称的特性,即写开销比读开销大很多。以ReRAM为例,其写操作只能串行地进行(实际上现在也有一些小规模并行的优化方法),而读操作(用作运算时也类似)可以大规模并行。并且,前文所述的“Program-ming-and-verify”的写方法也显著地增加了写开销。雪上加霜的是,这些新器件的写寿命往往有限,即在若干次写操作之后性质就会变差,甚至坏掉。这些都导致它们不适合进行频繁的更新操作。因此,虽然这些新器件用于神经网络的前向计算能取得很高的效率,但是对神经网络的训练这种需要频繁更新的操作很不友好。一种缓解问题的思路是在做训练时采用比“Programming-and-verify”更简单但也更近似的写入方式。另一种思路则是在训练时只用新器件存储权重的高位(因为高位更新不频繁),而将低位用其他传统方式来存储和计算。

,