Abstract

  机器学习任务正在广泛的领域和广泛的系统(从嵌入式系统到数据中心)中变得无处不在。与此同时,一小部分机器学习算法(特别是卷积和深度神经网络,即CNN和DNNs)在许多应用中被证明是最先进的。随着体系结构朝着由核和加速器混合组成的异构多核的方向发展,机器学习加速器可以实现罕见的效率(由于目标算法数量较少)和广泛的应用范围的组合。

  到目前为止,大多数机器学习加速器的设计都集中在高效实现算法的计算部分。然而,目前最先进的CNN和DNN的特点是它们的尺寸很大。在这项研究中,我们设计了一个适用于大规模CNN和DNN的加速器,特别强调了内存对加速器设计、性能和能量的影响。

  结果表明,在的小面积内,可以设计出具有高吞吐量、能够执行(如突触权重乘法和神经元输出加法等关键神经网络运算)的加速器;与的SIMD处理器相比,该加速器的速度提高了倍,总能量降低了倍。结果表明,该加速器具有较高的吞吐能力,能够在的小面积内完成(如突触权重乘法和神经元输出加法等关键的神经网络运算)的设计。在处布局后,获得了加速器的特性。在很小的空间内获得如此高的吞吐量,可以在广泛的系统和广泛的应用程序中打开最先进的机器学习算法的使用。

1. Introduction

  随着体系结构朝着由核和加速器混合组成的异构多核的方向发展,设计能够在灵活性和效率之间实现最佳折衷的加速器成为一个突出的问题。

  第一个问题是,人们应该主要为哪一类应用设计加速器?随着加速器的架构趋势,高性能和嵌入式应用程序中的第二个同步而重要的趋势正在发展:许多新兴的高性能和嵌入式应用程序,从图像/视频/音频识别到自动翻译、商业分析,以及所有形式的机器人都依赖于机器学习技术。这一趋势甚至开始渗透到我们的社区,在那里,Parsec[2]的大约一半基准测试可以使用机器学习算法来实现。Parsec[2]是一个套件,部分引入该套件是为了突出新类型应用程序的出现。这一应用趋势与机器学习的第三个同样显著的趋势相结合,在过去几年中,基于神经网络(特别是卷积神经网络[27]和深度神经网络[16])的少量技术已被证明在广泛的应用范围内是最先进的[25]。因此,由于目标算法的数量有限,因此有一个独特的机会来设计能够实现两全其美的加速器:显著的应用范围以及高性能和高效率。

  目前,这些工作负载大多在使用SIMD[41]的多核、GPU[5]或FPGA[3]上执行。然而,前述趋势已经被一些研究人员识别,他们提出了实现卷积神经网络[3]或多层感知器[38]的加速器;专注于其他领域(例如图像处理)的加速器也提出了机器学习算法所使用的一些原语的有效实现,例如卷积[33]。其他人已经提出了卷积神经网络的ASIC实现[13],或者其他自定义神经网络算法的ASIC实现[21]。然而,所有这些工作都首先并且成功地专注于高效地实现计算原语,但是它们要么为了简单而自愿忽略存储器传输[33,38],要么通过或多或少复杂的DMA将它们的计算加速器直接插入存储器[3,13,21]。

  虽然计算原语的有效实现是第一步也是重要的一步,其结果很有希望,但低效的存储器传输可能会潜在地使加速器的吞吐量、能量或成本优势失效,即Amdahl定律效应,因此,它们应该像处理器一样成为一阶问题,而不是第二步加速器设计中考虑的因素。不过,与处理器不同的是,在目标算法中可以考虑内存传输的特定性质,就像加速计算一样。这在机器学习领域尤其重要,在机器学习领域,有一种明显的趋势是扩大神经网络的规模,以实现更好的准确性和更多的功能[16,26]。

  在这项研究中,我们研究了一种能够适应最流行的最先进算法,即卷积神经网络(CNNS)和深度神经网络(DNNs)的加速器设计。我们将加速器的设计重点放在内存使用上,并研究了一种加速器体系结构和控制,以最大限度地减少内存传输并尽可能高效地执行它们。我们提出了一种65 nm的设计,在3.02mm2,485 mW的占地面积(不包括主存储器访问)下,每1.02 ns,即452GOP/s,可以并行执行496个16位定点运算。在最近CNN和DNN中发现的10个最大层上,该加速器比时钟频率为2 GHz的128位SIMD内核平均速度快117.87倍,能效(包括主存储器访问)高21.08倍。

  总括而言,我们的主要贡献如下:

  • 一种用于大规模CNN和DNN的综合(放置和布线)加速器设计,最先进的机器学习算法。

  • 该加速器在小面积、功耗和能量占用方面实现了高吞吐量。
  • 加速器设计关注的是内存行为,测量并不局限于计算任务,它们将内存传输的性能和能量影响考虑在内。

  该文件组织如下。在第2节中,我们首先提供最近的机器学习技术的入门读物,并介绍组成CNN和DNN的主要层。在第三节中,我们分析和优化这些层的存储行为,为基线和加速器设计做准备。在第4节中,我们解释为什么大规模CNN或DNN的ASIC实现不能与小型NN的直接ASIC实现相同。我们在第5节介绍了我们的加速器设计。方法学介绍在第6节,第7节的实验结果,第8节的相关工作中。

2. Primer on Recent Machine-Learning Techniques | 最新机器学习技术入门读本

  尽管神经网络在机器学习领域的作用一直不稳定,即最初在20世纪80/90年代被炒作,然后随着支持向量机的出现而逐渐淡出人们的视线[6]。自2006年以来,神经网络的一个子集已经出现,在广泛的应用中实现了最先进的机器学习精度,部分原因是计算机视觉的神经科学模型的进步,如HMAX[37]。该神经网络子集包括深度神经网络(DNNs)[25]和卷积神经网络(CNNs)[27]。DNN和CNN是强相关的,它们在卷积层的存在和/或性质上特别不同,见后面。

  处理与培训。目前,我们在加速器上实现了输入的快速处理(前馈),而不是训练(反向路径)。这源于技术和市场考虑。从技术上讲,人们经常有一种重要的误解,认为在线学习对于许多应用程序来说都是必要的。相反,对于许多工业应用而言,离线学习就足够了,其中神经网络首先针对一组数据进行训练,然后运送给客户,例如关于手写数字、车牌号、要识别的人脸或对象的数目等进行训练;网络可以周期性地离线并重新训练。虽然今天,机器学习研究人员和工程师特别需要加快培训速度的架构,但这只是一个很小的市场,目前,我们专注于更大的最终用户市场,他们需要快速/高效的前馈网络。有趣的是,最近涉足硬件加速器的机器学习研究人员也做出了同样的选择。尽管如此,由于训练中使用的计算和访问模式的性质(特别是反向传播)与前向路径的性质相当相似,我们计划稍后在加速器中增加支持训练的必要功能。

  一般结构。尽管深度神经网络和卷积神经网络有不同的形式,但它们有足够的共同性质,可以定义一个通用的公式。通常,这些算法由(可能大量)层组成;这些层是按顺序执行的,因此可以独立考虑(和优化)它们。每一层通常包含几个称为功能地图的子层;然后我们使用术语输入功能地图和输出功能地图。总体而言,有三种主要的层:层次的大部分由卷积和合并(也称为子采样)层组成,在网络的顶部有一个由一个或几个层组成的分类器。

  卷积层。卷积层的作用是将一个或多个本地过滤器应用于来自输入(先前)层的数据。因此,输入和输出特征地图之间的连接是局部的,而不是完全的。考虑输入是图像的情况,卷积是输入层的子集(窗口)和相同维度的核之间的2D变换,见图1。核值是输入层和输出(卷积)层之间的突触权重。由于一个输入层通常包含多个输入特征映射,并且由于输出特征映射点通常是通过对所有输入特征映射的同一窗口应用卷积来获得的,请参见图1,核是3D的,即,其中是输入特征映射的数目。请注意,在某些情况下,连接性是稀疏的,即并非所有输入特征映射都用于每个输出特征映射。卷积层的典型代码如图7所示,参见原始代码。将非线性函数应用于卷积输出,例如。卷积层的特征还在于两个连续窗口(一维或二维)之间的重叠,参见步骤 以了解循环

  在某些情况下,将相同的核应用于输入层的所有窗口,即,在整个输入特征映射上隐式共享权重。这是CNN的特征,虽然内核可以特定于DNNs[26]中输出特征映射的每个点,但我们随后使用术语私有内核。

  合并图层。池化层的作用是聚合一组邻居输入数据中的信息。同样,在图像的情况下,它仅用于在给定窗口内保留图像的显著特征和/或以不同的比例这样做,请参见图1。汇集图层的一个重要副作用是降低了要素地图的维度。池层的示例代码如图8所示(请参阅原始代码)。请注意,每个要素地图是单独池化的,即2D池化,而不是3D池化。合用可以以各种方式进行,一些优选的技术是平均值和最大运算;合用之后可以是非线性函数,也可以不是。

  分类器层。卷积和池层是在深层层次结构中交织的,而层次结构的顶部通常是一个分类器。分类器可以是线性或多层(通常是2层)感知器,见图1。如图5所示,示例感知器层见原始代码。像卷积层一样,非线性函数被应用到神经元输出中,通常是一个b型,例如:;不同于卷积或池层,分类器通常聚合(平坦)所有特征映射,所以在分类器层中没有特征映射的概念。

3. Processor-Based Implementation of (Large) Neural Networks | 基于处理器的(大型)神经网络的实现

  加速大规模神经网络的独特之处在于潜在的高内存流量。在本节中,我们详细分析了第2节中提到的不同层的局部性,我们对这些层的基于处理器的实现进行了调整,以便为我们的基线准备和加速器的设计和使用。我们将局部分析/优化应用到各个层次上,并通过4个基准层(1,CONV3,CONV5,POOL3)对这些变换的带宽影响进行了说明,并在第6节中详细说明了它们的特性。

  对于这个部分的内存带宽测量,我们使用一个缓存模拟器,插入到一个虚拟计算结构中,我们没有假设,除非它能够处理神经元,每个周期都有突触。缓存层次结构由intel core i7驱动:L1为64位,64字节行,8路;可选L2是2MB、64byte、8路。与核心i7不同,我们假设缓存有足够的银行/端口来为输入神经元提供字节,并且对于突触来说,字节。对于大型来说,这种缓存的成本可能会令人望而却步,但它只用于我们对局部性和带宽的限制研究;我们使用

3.1 Classifier Layers | 分类器层

1
2
3
4
5
6
7
8
9
10
11
12
13
for (int nnn = 0; nnn ¡ Nn; nnn += Tnn) { // tiling for output neurons;
for (int iii = 0; iii ¡ Ni; iii += Tii) { // tiling for input neurons;
for (int nn = nnn; nn ¡ nnn + Tnn; nn += Tn) {
for (int n = nn; n ¡ nn + Tn; n++)
sum[n] = 0;
for (int ii = iii; ii ¡ iii + Tii; ii += Ti)
// — Original code —
for (int n = nn; n < nn + Tn; n++)
for (int i = ii; i < ii + Ti; i++)
sum[n] += synapse[n][i] * neuron[i];
for (int n = nn; n < nn + Tn; n++)
neuron[n] = sigmoid(sum[n]);
}}}
Figure 5. Pseudo-code for a classifier (here, percption) layer (original loop nest + locality optimization)

  我们考虑感知器分类器层,见图2和5;平铺循环简单地反映了计算结构可以同时处理具有突触的神经元。内存传输总数为(加载的输入+加载的突触+写入的输出):。对于示例层CLASS1,相应的内存带宽很高,为120 Gb/s,请参见图6中的CLASS1-Original。下面我们将解释如何可能降低此带宽,有时会大幅降低。

  输入/输出神经元。再次考虑图2和图5的代码。对于每个输出神经元,输入神经元被重复使用,但是由于输入神经元的数量可以在几十到几十万之间的任何范围内,它们通常不会在L1高速缓存中命中。因此,我们用平铺因子来平铺回路(输入神经元)。平铺的一个典型权衡是,改进一个参考(这里的神经元[i]是输入神经元)会增加另一个参考(输出神经元部分和的)的重用距离,因此我们也需要平铺第二个参考,因此循环和输出神经元部分和的平铺系数。正如预期的那样,瓦片大大降低了输入神经元的存储带宽需求,而输出神经元的存储带宽需求则有所增加,尽管幅度很小。层记忆行为现在由突触主导。

  突触。在感知器层中,所有突触通常都是唯一的,因此在该层内不存在重用。另一方面,突触在网络调用之间重复使用,即,对于呈现给神经网络的每个新输入数据(也称为“输入行”)重复使用。因此,足够大的L2可以存储所有的网络突触,并利用该位置。对于具有私有内核的DNN来说,这是不可能的,因为突触的总数在数千万或数亿(迄今为止最大的网络有10亿个突触[26])。但是,对于具有共享内核的CNN和DNN,突触总数都在数百万个范围内,这在L2缓存的范围内。在图6中,请参阅,我们模拟了这样一种情况,即只考虑感知器层即可跨网络调用重用;因此,总带宽需求现在已大幅降低。

3.2 Convolutional Layers | 卷积层

  我们考虑二维卷积层,见图3和图7。卷积层相对于分类器层的两个显著特征是存在输入和输出特征映射(循环)和核(循环)。

  输入/输出。输入和输出有两种重用机会:用于扫描(二维)输入层的滑动窗口和跨个输出特征映射的重用,见图3。前者最多对应于重用,后者对应于NN重用。我们在图7中为前者平铺(平铺),但我们通常不需要为后者平铺,因为要重用的数据,即的一个核,适合L1数据高速缓存,因为通常是10的量级,而可以在小于10到几百之间变化;当然,当不是这种情况时,我们可以平铺输入特征地图()并再次引入第二级平铺循环

  突触。对于具有共享内核的卷积层(参见第2节),相同的内核参数(突触权重)在所有输出特征映射位置上重复使用。因此,总带宽已经很低,如图6中的层CONV3所示。然而,由于总的共享内核容量是,它可能会超过L1高速缓存容量,因此我们再次平铺输出特征地图(平铺)以将其降至。因此,总体内存带宽可以进一步减少,如图6所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
for(intyy=0;yyiNyin;yy+=Ty){
for(intxx=0;xxiNxin;xx+=Tx){
for(intnnn=0;nnnjNn;nnn+=Tnn){
//-Original code-(excluding nn, ii loops)
int yout=0;
for(inty=yy;y<yy+Ty;y+=sy){//tiling fory;
int xout=0;
for(intx=xx;x<XX+Tx;X+=sx){//tiling forx;
for (int nn = nnn; nnn + Tnn; nn+=Tn){
for(intn=nn;n<nn+Tn;n++)
sum[n]=0;
//sliding window;
for(intky=0;ky<Ky;ky++)
for(intkx=0;kx<Kx;kx++)
for(intii=0;ii<Ni;ii+=Ti)
for(intn=nn;n<nn+Tn;n++)
for(inti=ii;i<ii+Ti;i++)
//version with shared kernels
sum[n]+=synapse[ky][kx][n][i]
*neuron[ky+y][kx+x][i];
//version with private kernels
sum[n]+=synapse[yout][xout][ky][kx][n][i]}
*neuron[ky+y][kx+x][i];
for(intn=nn;n<nn+Tn;n++)
neuron[yout][xout][n]=non_linear_transform(sum[n]);
}xout++;}yout++;
}}}}
Figure 7. Pseudo-code for convolutional layer (original loop nest + locality optimization), both shared and private kernels versions

  对于具有私有内核的卷积层,突触都是唯一的,没有重用,就像分类器层一样,因此具有图6中CONV5的相似突触带宽。至于分类器层,如果L2容量足够的话,跨网络调用重用仍然是可能的。尽管阶跃系数()和输出特征图的稀疏输入(参见第2节)可以大幅减少私有内核突触权重的数量,但对于CONV5等非常大的层,它们的范围仍然在数百兆字节,因此将大大超过L2容量,这意味着高内存带宽,请参见图6。

  值得注意的是,机器学习社区中关于共享内核与私有内核的争论正在进行[26,35],拥有私有内核而不是共享内核的机器学习重要性仍然不清楚。由于它们可能导致显著不同的体系结构性能,这可能是体系结构/性能社区参与机器学习辩论的情况。

3.3 Pooling Layers | 池化图层

  现在我们考虑汇集层,见图4和图8。与卷积层不同,输入和输出特征图的数量是相同的,更重要的是,没有核,即没有要存储的突触权重,并且输出特征图元素仅由输入特征图元素确定,即2D窗口(而不是用于卷积层的3D窗口)。因此,唯一的重用来源来自滑动窗口(而不是滑动窗口和输出特征映射的组合效果)。由于重用机会较少,输入神经元的存储带宽高于卷积层,并且平铺带来的改进不那么显著,请参见图6。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
for(intyy=0;yyiNyin;yy+=Ty){
for(intxx=0;xxiNxin;xx+=Tx){
for(intii=0;iii;Ni;ii+=Tii)
//-Original code-(excluding ii loop)
int yout =0;
for(inty=yy;y<yy+Ty;y+=sy){
int xout = 0;
for(intx=xx;x<xx+Tx;X+=SX){
for (int ii = iii ; i < ii + Tii ; ii + = Ti )
for(inti=ii;i<ii+Ti;i++)
value[i]=0;
for(intky=0;ky<Ky;ky++)
for(intkx=0;kx<Kx;kx++)
for(inti=ii;i<ii+Ti;i++)
//version with average pooling;
value[i]+=neuron[ky+y][kx+x][i];
//version with max pooling;
value[i]=max(value[i],neuron[ky+y][kx+x][i]);
}}}}
//for average pooling;
neuron[xout][yout][i]=value[i]/(Kx*Ky);
xout++;} yout++;
}}}
Figure 8. Pseudo-code for pooling layer (original loop nest + locality optimization).

4. Accelerator for Small Neural Networks | 用于小型神经网络的加速器

  在这一部分中,我们首先评估一种实现硬件神经网络加速器的“幼稚”和“贪婪”的方法,其中所有神经元和突触都在硬件中布局,内存仅用于输入行和存储结果。虽然这些神经网络可以潜在地达到最佳的能源效率,但我们表明它们是不可伸缩的。尽管如此,我们仍然使用这样的网络来研究可以合理地在硬件中实现的神经元的最大数量。

4.1 Hardware Neural Networks | 硬件神经网络

  将神经网络映射到硅上最自然的方法是完全布局神经元和突触,以便硬件实现与神经网络的概念表示相匹配,请参见图9。每个神经元都实现为逻辑电路,而突触实现为锁存器或RAM。这种方法最近已经用于基于感知器或尖峰的硬件神经网络[30,38]。它与一些嵌入式应用程序兼容,在这些应用程序中,神经元和突触的数量可以很少,而且它可以提供高速和低能量,因为数据传输的距离非常小:从一个神经元到下一层的神经元,以及从一个突触锁存器到相关的神经元。例如,90-10-10(90个输入,10个隐藏,10个输出)感知器[38]的执行时间为15 ns,比核心能量降低974倍。

4.2 Maximum Number of Hardware Neurons ? | 硬件神经元的最大数量?

  然而,面积、能量和延迟随神经元数量的增加呈二次曲线增长。我们综合了不同维度的神经网络层的ASIC版本,并在图10中报告了它们的面积、关键路径和能量。我们使用Synopsys ICC作为布局和布线,并使用TSMC 65 nm GP库,标准VT。硬件神经元执行以下操作:输入和突触相乘,所有这些相加,然后是S形,见图9。Tn×T1层是TN神经元的一层,每一层都有T1突触。16x16层需要小于0.71mm2,但32x32层已经需要2.66mm2。考虑到大规模神经网络的神经元数以千计,只有一层的完整硬件布局可能在数百或数千mm2的范围内,因此,这种方法对于大规模神经网络是不现实的。

  对于这样的神经网络,只有一小部分神经元和突触可以在硬件中实现。矛盾的是,旧的神经网络设计(如Intel ETANN[18])在20世纪90年代初就是这种情况,不是因为神经网络在当时已经很大,而是因为硬件资源(晶体管数量)自然要稀缺得多。其原理是分时扫描物理神经元,并使用片上RAM存储突触和隐藏层的中间神经元值。然而,在那个时候,许多神经网络都足够小,以至于所有的突触和中间神经元的值都可以在神经网络内存中fit。由于这种情况已经不再是这样,大规模神经网络加速器设计的主要挑战之一已经成为计算和存储层次之间的相互作用。

5. Accelerator for Large Neural Networks | 用于大型神经网络的加速器

  在这一部分中,我们借鉴第三节和第四节的分析,设计了一个适用于大规模神经网络的加速器。

  加速器的主要部件如下:输入神经元的输入缓冲器(NBIN),输出神经元的输出缓冲器(NBOUT),以及第三个突触权重缓冲器(SB),它们连接到我们称为神经功能单元(NFU)的计算块(执行突触和神经元计算)和控制逻辑(CP),见图11。我们首先fi下面描述NFU,然后我们集中讨论并解释加速器存储元件的原理。

5.1 Computations: Neural Functional Unit (NFU) | 计算:神经功能单元(NFU)

  NFU的精神是将一层神经元分解成由输入/突触和输出神经元组成的计算块(flblock)。这对应于用于ClassifiEr和卷积层两者的循环I和N,见图5和图7,并且对应于用于汇聚层的循环I,见图8。

  算术运算符。每种图层类型的计算可以分2个阶段或3个阶段进行。对于Classifier层:突触×输入的乘法,所有乘法的相加,S形。对于卷积层,级是相同的;最后一级(Sigmoid或其他非线性函数)的性质可以改变。对于池化层,没有乘法(没有突触),并且池操作可以是平均值或最大值。请注意,加法器有多个输入,它们实际上是加法器树,见图11;第二级还包含用于合并层的移位器和最大运算符。

  交错的管道。我们可以对所有2或3个操作进行流水线操作,但流水线必须交错:第一个或前两个阶段(分别用于池、分类器和卷积层)作为正常流水线级操作,但第三级仅在执行完所有添加之后才有效(对于分类器层和卷积层;对于池化层,在第三级中没有操作)。从现在开始,我们将NFU管道的第n阶段称为NFU-n。

  NFU-3功能实现。如文献[23,38]所述,NFU-3(用于分类器和卷积层)的Sigmoid可以使用分段线性内插()有效地实现,精度损失可以忽略不计(16个段就足够了)[24],见图9。就运算符而言,它对应于两个 16x1 16位多路复用器(用于段边界选择,即)、一个16位乘法器(16位输出)和一个16位加法器来执行内插。16段系数(ai,bi)存储在小RAM中;这允许仅通过改变RAM段系数来实现任何功能,而不仅仅是Sigmoid(例如,双曲正切、线性函数等);段边界是硬连线的。

  16位定点算术运算符。我们使用16位定点算术运算符,而不是字长(例如,32位)浮点运算符。虽然这看起来可能令人惊讶,但文献中有充分的证据表明,即使是更小的运算符(例如,8位或更少)对神经网络的准确性几乎没有影响[8,17,24]。为了说明和进一步支持fiRM这一概念,我们在UC Irvine机器学习存储库中的数据集上训练并测试了多层感知器,参见图12,在标准MNIST机器学习基准(手写数字)[27]上,参见表1,使用16位定点和32位浮点运算符;我们使用10倍交叉验证进行测试。对于定点运算符,整数部分使用6位,小数部分使用10位(我们在整篇文章中都使用这种定点配置)。结果如图12所示,在fiRm中,这种权衡对精度的影响非常小。目前我们保守地使用16位定点,但将来我们会探索更小的或可变大小的运算符。注意,算术运算符是截断的,即它们的输出是16位;我们使用具有校正常数的标准n位截断乘法器[22]。如表2所示,其面积比65 nm的32位浮点乘法器小6.10倍,功耗低7.33倍,CAD工具方法见第6节。

5.2 Storage: NBin, NBout, SB and NFU-2 Registers | 存储:NBIN、NBOUT、SB和NFU-2寄存器

  加速器的不同存储结构可以被解释为便签本的修改过的(modifi)缓冲器。虽然高速缓存是通用处理器的优秀存储结构,但由于高速缓存访问开销(标签检查、关联性、行大小、推测性读取等)和高速缓存冲突[39],它是利用重用的次优方式。高效的替代方案,便签簿,在VLIW处理器中使用,但是众所周知,它很难编译。然而,专用加速器中的便签簿实现了这两个领域的最佳效果:高效的存储和高效且容易地利用本地,因为只有少数算法需要手动调整。在这种情况下,我们几乎可以直接将第3节中介绍的位置转换转换为缓冲区的映射命令,主要是调制平铺因子。第5.3.2节提供了一个代码映射示例。

  下面我们解释加速器的存储部分是如何组织的,以及它克服了缓存体系结构的哪些限制。

5.2.1 Split buffers | 拆分缓冲区

  如前所述,我们将存储划分为三个结构:输入缓冲区(NBIN)、输出缓冲区(NBOUT)和突触缓冲区(SB)。

  宽度。拆分结构的第一个好处(fit)是将SRAM调整为适当的读/写宽度。NBIN和NBOUT的宽度均为字节,而SB的宽度为字节。单个读取宽度大小(例如,与高速缓存线大小一样)将是较差的折衷。如果将其调整为突触,即如果行大小为,则从宽的数据库中读取字节会产生显著的能量损失,见图13,图13显示了65 nm处TSMC工艺的SRAM读取能量作为存储体宽度的函数。如果将行大小调整为神经元,即如果行大小为,则读出字节具有显著的时间代价。将存储拆分为专用结构允许为每个读取请求获得最佳时间和精力。

  冲突。分割存储结构的第二个好处(fit)是避免将在高速缓存中发生的冲突。这一点尤其重要,因为出于成本和能源(泄漏)的原因,我们希望使存储结构的尺寸保持较小。另一种解决方案是使用高度关联的高速缓存。考虑这些约束:高速缓存线(或端口数)需要很大()才能以高速率为突触提供服务;由于我们希望保持较小的高速缓存大小,因此容忍如此长的高速缓存线的唯一替代方案是高关联性。然而,在n路高速缓存中,通过推测性地并行读取所有n路/存储体来实现快速读取;结果,关联高速缓存的能量成本迅速增加。即使从8路关联32KB高速缓存读取64字节的能量也比从65 nm的直接映射高速缓存读取32字节的能耗高3.15倍;使用Cacti[40]进行测量。即使只有64字节行,Corei7的一级32KB数据高速缓存也已经是8路关联的,因此我们需要更大的关联性来处理非常大的行(对于,行大小将是512字节长)。换句话说,在我们的情况下,高度关联的高速缓存将是一种昂贵的能源解决方案。拆分式存储和对本地行为的精确了解允许完全消除数据冲突。

5.2.2 Exploiting the locality of inputs and synapses. | 利用输入和突触的局部性。

  DMA。为了利用空间局部性,我们实现了三个DMA,每个缓冲区一个(两个加载DMA,一个用于输出的存储DMA)。DMA请求以指令的形式向NBIN发出,稍后将在第5.3.2节中介绍。这些请求缓存在与每个缓冲区相关的单独FIFO中,请参见图11,一旦DMA发送了前一条指令的所有内存请求,它们就会立即发出。这些DMA请求FIFO可使向所有缓冲区和NFU发出的请求与当前缓冲区和NFU操作解耦。因此,只要有足够的缓冲区容量,就可以提前很长时间预加载DMA请求,以容忍较长的延迟;这种预加载类似于预取,尽管没有推测。由于NBIN(和SB)同时用作重复使用和预加载缓冲区的便签簿,因此我们使用双端口SRAM;TSMC 65 nm库将64条目NB的双端口SRAM的读取能量开销评为24%。

  旋转NBIN缓冲器,用于输入神经元的临时重用。所有层的输入被分割成块,这些块在nbin中被fit,并通过实现nbin作为循环缓冲区来重用。实际上,轮换是通过改变寄存器索引自然实现的,很像在软件实现中,不存在缓冲器条目的物理(和昂贵的)移动。

  NBIN中的局部转置用于合并图层。对于(输入)神经元的数据结构组织,在卷积层和池层之间存在张力。如前所述,Kx,Ky通常很小(通常小于10),而Ni大约大一个数量级。因此,使用输入特征映射作为三维神经元数据结构的最内层索引,内存获取效率更高(大跨度-1访问)。然而,这对于合并图层是不方便的,因为每个输入特征地图计算一个输出,即,仅使用K x×Ky数据(而在卷积图层中,计算一个输出数据需要所有K x×K y×Ni数据)。因此,对于池化层,逻辑数据结构组织是将kx,ky作为最里面的维度,以便计算一个输出所需的所有输入都连续地存储在NBIN缓冲器中。我们通过在NBIN中引入映射函数来解决此问题,该映射函数具有本地调换循环k y、k x和循环i的效果,以便数据沿着循环i加载,但它存储在NBIN中,因此首先沿着循环k y、k x发送到NFU;这是通过在加载时交错NBIN中的数据来实现的,请参见图14。

  对于突触和SB,如第3节所述,要么没有重用(分类器层、具有私有内核的卷积层和池层),要么在卷积层中重用共享内核。对于OUTPUT和NBOUT,我们需要重用部分和,即参见图5中的参考SUM[n]。此重用需要下一节所述的额外硬件修改fi阳离子。

5.2.3 Exploiting the locality of outputs. | 利用输出的局部性

  在分类器层和卷积层,对于NBIN中包含的一组输入神经元,计算Tn个输出神经元的部分输出和。然后,输入神经元被用于另一块Tn输出神经元,等等。这就产生了两个问题。

  专用寄存器。首先,虽然输入神经元的块是从NBIN加载并用于计算部分和的,但是让部分和离开NFU流水线,然后为NBIN缓冲器的每个条目将其重新加载到流水线中将是低效的,因为数据传输是能量消耗的主要来源[14]。因此,我们在NFU-2中引入了专用寄存器来存储部分和。

  循环缓冲区。其次,一个更复杂的问题是,当NBIN中的输入神经元被重新用于一组新的Tn输出神经元时,如何处理Tn部分和。我们不是将这些Tn部分和发送回内存(稍后在下一块输入神经元加载到NBIN时重新加载它们),而是暂时将它们轮换出到NBOUT。先验地,这是nbout的冲突角色,nbout还用于存储要写回内存(写缓冲区)的最终输出神经元。但在实践中,只要没有将所有输入神经元都整合到部分和中,NBout就是空闲的。因此,我们可以通过将Tn部分和轮换到NBout来将其用作临时存储缓冲区,如图11所示。自然,在输出神经元上迭代的循环必须平铺,以便同时计算其部分和的输出神经元不会超过NBout的容量,但这是通过类似于图5和图7中的循环nnn的二级平铺来实现的。因此,NBout不仅连接到NFU-3和存储器,而且还连接到NFU-2:NBout的一个条目可以加载到NFU-2的专用寄存器中,并且这些寄存器可以存储在NBout中。

5.3 Control and Code | 控件和代码

5.3.1 CP

  在本节中,我们将介绍加速器的控制。控制的一种方法是硬连线三个目标层。虽然这仍然是未来的一个选择,但目前,我们已经决定使用控制指令来探索层的不同实现(例如,分区和调度),并为机器学习研究人员提供尝试不同层实现的灵活性。

  一层执行被分解成一组指令。粗略地说,一条指令对应于分类器层和卷积层的环路II,i,n,见图5和7,以及池层中的环路II,i(使用第5.2.3节所述的交织机制),见图8。指令存储在与控制处理器(CP)相关的SRAM中,见图11。CP驱动三个缓冲器和NFU的DMA的执行。术语“处理器”只涉及前面提到的“指令”,稍后将在第5.3.2节中介绍,但它几乎没有处理器的传统功能(主要是一台PC和一个用于循环索引和地址计算的加法器);从硬件的角度来看,它更像是一个可配置的FSM。

5.3.2 Layer Code. | 图层代码

  每条指令都有对应于CP本身、三个缓冲器和fi的NFUVE槽,参见表3。

  因为有CP指令,所以需要代码生成,但在我们的例子中,编译器就太过分了,因为只需要生成三种主要类型的代码。因此,我们为这三层实现了三个专用的代码生成器。在表4中,我们给出了一个为分类器/感知器层生成的代码示例。由于Tn=16(每缓存行16×16位数据),并且NBIN有64行,所以它的容量是2KB,所以它不能包含所有的输入神经元(Ni=8192,所以16KB)。结果,代码被分解为在2KB的块上操作;注意,NBIN的第一条指令是LOAD(从存储器中取出的数据),并且它被标记为重用(紧接在加载之后的标志);下一条指令是READ,因为这些输入神经元在缓冲器中被旋转用于Tn神经元的下一块,并且READ也被标记为被重用,因为有8个这样的旋转(16KB2KB);同时,请注意,第一条(和下一条)指令的NFU-2输出为NBOUT,即部分输出神经元和旋转为NBOUT,如第5.2.3节所述,这就是NBOUT指令为WRITE的原因;另请注意,NFU-2的输入已复位(第一块输入神经元,寄存器复位)。最后,当最后一块输入神经元被发送时(表中的最后一条指令),NBout的(存储)DMA被设置为写入512字节(256个输出),并且NBout指令被存储;下一条指令的NBout写入操作将是NOP(在第一个块设置DMA,并自动将数据存储回存储器,直到DMA结束)。

  注意,该体系结构可以实现每个图像或批处理[41],只有生成的层控制代码会改变。

6. Experimental Methodology | 实验方法论

  尺寸。我们使用三种不同的工具来测量性能/能量。

  加速器模拟器。我们实现了加速器结构的自定义周期精确度、位精确度的C++模拟器,最初用于架构探索,后来用作Verilog实现的规范。该模拟器还用于测量循环次数的时间。它被插入到允许高达250 Gb/s带宽的主内存模型中。

  CAD工具。对于面积、能量和关键路径延迟(周期时间)测量,我们实现了一个Verilog版本的加速器,我们首先使用Synopsys Design Compiler使用TSMC 65 nm GP标准VT库进行合成,然后使用Synopsys ICC编译器进行放置和布线。然后,我们使用Synopsys VCS对设计进行了仿真,并使用黄金时间px估计了功耗。

  SIMD。对于SIMD基线,我们使用GEM5+McPAT[28]组合。我们使用4个问题的超标量x86内核,带有128位(8×16位)SIMD单元(SSE/SSE2),时钟频率为2 GHz。内核具有192个条目的ROB和64个条目的加载/存储队列。一级数据(和指令)高速缓存为32KB,二级高速缓存为2MB;这两个高速缓存均为8路联合高速缓存,并使用64字节线;这些高速缓存特性与英特尔酷睿i7的高速缓存特性相对应。到L2的L1未命中等待时间为10个周期,到存储器的L2未命中等待时间为250个周期;存储器总线宽度为256位。通过使用McPAT提供的数据(例如,256位读取存储器访问的能量成本为17.6nJ),我们已经对加速器和模拟器的主存储器访问的能量成本进行了调整。

  我们实现了不同层代码的SIMD版本,如第3节所述,我们手动调优了它的局部性(对于每一层,我们执行随机探索以找到好的平铺因子);我们使用DEFAULT-O优化级别编译这些程序,但内部循环是用汇编语言编写的,以最大限度地利用SIMD单元。为了评估SIMD内核的性能,我们还实现了下面给出的不同基准层的标准C++版本,平均(几何平均值),我们观察到SIMD内核的执行时间是x86内核的3.92倍,能耗是x86内核的3.74倍。

  基准。对于基准,我们选择了几个最新的大型神经网络结构中最大的卷积、汇集和/或分类器层。表5显示了这10个层的特征以及相关神经网络和任务的描述。

7. Experimental Results | 实验结果

7.1 Accelerator Characteristics after Layout | 布局后的加速器特性

  当前版本使用Tn=16(16个硬件神经元,每个具有16个突触),因此该设计在NFU-1中包含256个16位截断乘法器(用于分类器和卷积层),在NFU-2中包含16个加法器树,每个加法器包含15个加法器(对于相同的层,如果使用平均值,则加上合并层),以及NFU-2中的16输入移位器和最大值(用于合并层),以及16位截断乘法器加上NFU-3中的16个加法器(用于分类器和卷积层,以及可选的用于合并层)。对于分类器和卷积层,NFU-1和NFU-2每个周期都是活动的,每个周期实现256+16×15=496次定点运算;在0.98 GHz,这相当于452 GOP/s(每秒千兆定点运算)。在层的末尾,当NFU-1和NFU-2处理剩余数据时,NFU-3也将处于活动状态,在短时间内达到496+2×16=528次/周期(482GOP/s)的峰值活动。

  我们使用Synopsys工具完成了65 nm处Tn=16和64入口缓冲器的综合和布局,见图15。主要特性和按元件类型和功能块细分的功耗/面积如表6所示。我们通过在NFU-1(乘法器)、NFU-2(加法器树)和NFU-3(分段线性函数近似)中引入3级流水线,将关键路径延迟降至1.02 ns,共8个流水线级。在NFU-1(乘法器)、NFU-2(加法器树)和NFU-3(分段线性函数近似)中引入3级流水线,使关键路径延迟降至1.02 ns。目前,关键路径在负责从NBIN/NBOUT中读取数据的问题逻辑中;下一个版本将重点介绍如何减少或输送此关键路径。总RAM容量(NBIN+NBOUT+SB+CP指令)为44KB(CP RAM为8KB)。面积和功耗分别由缓冲器(NBIN/NBOUT/SB)控制,分别为56%和60%,NFU紧随其后,分别为28%和27%。小区总功率的百分比为59.47%,但路由网络(包括在表细分的不同组成部分中)在总功率中所占的比例很大,为38.77%。在65 nm处,由于加速器的高翻转率,漏功率在1.73%几乎可以忽略不计。

  最后,我们还评估了Tn=8的设计,因此在NFU-1中有64个乘法器。该设计的总面积为0.85mm2,即由于缓冲器宽度减小和算术运算符数量减少,比Tn=16小3.59倍。我们计划在不久的将来研究Tn=32或64的更大的设计。

7.2 Time and Throughput | 时间和吞吐量

  在图16中,我们报告了加速器在SIMD上的加速比,请参阅SIMD/ACC。回想一下,我们使用的是128位SIMD处理器,因此每个周期能够执行多达8个16位操作(我们在SIMD中自然也使用16位定点操作)。如7.1节所述,加速器每个周期为分类器层和卷积层执行496次16位操作,即比SIMD内核多62倍(4968)。我们经验地观察到,在这两种类型的层上,加速器的速度平均是SIMD核的117.87倍,因此比计算运算符的比率(62倍)高出约2倍。我们测量到,对于分类器层和卷积层,SIMD内核平均每个周期执行2.01个16位运算,而不是每个周期8个运算的上限。我们将其追溯到两个主要原因。

  首先,NBIN和SB缓冲区中的预加载和重用的适当组合带来了更好的延迟容忍度;请注意,我们没有在SIMD内核中实现预取器,这将在一定程度上弥补这一差距。这解释了具有最大特征地图大小的层1、类3和层5的高性能差距,这些层具有最大的特征地图大小,因此具有最大的空间局部性,从而使fi从预加载中受益最大,从而使它们的性能提升平均为629.92倍,大约是其他卷积层的3倍;我们预计SIMD核中的预取器将抵消这种性能提升。DMA沿着输入特征映射维度利用NBIN中的空间局部性,并且对于较小的NI,DMA必须发出许多短内存请求,这降低了效率。其余卷积层(CONV1到CONV4)的平均加速比为195.15倍;由于私有内核和较小的空间局部性,CONV2的性能较差(130.64倍)。由于仅使用NFU-2中的加法器树(496个运算符中有240个运算符),POOL3和POOL5分别使用25.73x和25.52x,因此池化层的整体性能较低。

  为了进一步分析POOL1的相对较差的行为(仅为SIMD的2.17倍),我们测试了加速器的一种配置,其中所有操作数(输入和突触)都为NFU做好了准备,即NBIN、SB和NBOUT的理想行为;我们称此版本为“理想”,参见图16。我们看到,POOL1和CONV2上的加速器明显慢于理想配置(分别为66.00x和16.14x)。这是由于它们的输入/输出特征映射的大小较小(例如,对于POOL1,N1=12),并且用于POOL1的运算符较少。到目前为止,加速器面向的是大型层,但我们可以通过实现2D或3D DMA(循环上的DMA请求)来解决这一弱点;我们将此优化留到以后的工作中。

  SIMD的加速比超过62倍的第二个原因在于控制和调度开销。在加速器中,我们试图将丢失的周期降到最低。例如,当输出神经元部分和旋转到NBOUT(在发送回NFU-2之前)时,最旧的缓冲行(部分和)会急切地向外旋转到NBOUT/NFU-2输入锁存器,并且NFU-2中的多路复用器确保此锁存器或NFU-2寄存器用作NFU-2级计算的输入;这允许在没有任何流水线停滞的情况下旋转。几个这样的设计优化帮助实现了仅比理想加速器慢4.36倍的速度,参见图16,事实上,只有在不包括CONV2和POOL1的情况下,慢速才是2.64倍。

7.3 Energy | 能源

  在图17中,我们提供了SIMD内核和加速器之间的能量比。虽然平均能量比高达21.08x,但实际上比之前报道的处理器和加速器之间的能量比小了一个数量级以上;例如,Hameed等人。[14]报告能量比约为500x,小型多层感知器的能量比为974x[38]。较小的比率很大程度上是由于在存储器访问上花费的能量,这一点在上述两项研究中自愿没有考虑在内。与这两个加速器和其他加速器一样,通过更高效的计算运算符(特别是在我们的例子中,大量小型16位定点截断乘法器)和靠近运算符的小型自定义存储(64条目NBIN、NBOUT、SB和NFU-2寄存器)的组合,计算的能源成本已大大降低。因此,现在存在能量的Amdahl定律效应,只有通过降低主存储器访问的能量成本才能实现任何进一步的改进。我们试图人为地将SIMD和加速器中的主存储器访问的能量成本设置为0,我们观察到加速器的平均能量降低增加了一个数量级以上,与之前的结果一致。

  图18中加速器消耗的能量细目进一步说明了这一点,其中主存储器访问的能量显然占主导地位。一个遥远的第二个是具有共享核(CONV1,CONV3,CONV4)的卷积层的NBIN/NBOUT的能量。在这种情况下,一组共享内核保留在SB中,因此由于突触导致的内存流量变得非常低,如第3节(共享内核+平铺)中所解释的,但是仍然必须为每组新的共享内核重新加载输入神经元,因此仍然存在明显的能量消耗。池化层(POOL1、POOL3、POOL5)中的计算逻辑的能量同样是一个遥远的第二开销,这一次是因为没有要加载的突触。池层的能耗降低稍高(平均为22.17倍),参见图17,这是由于未使用SB缓冲区(无突触),而且由于NBIN的宽度较小,单独访问NBIN的成本相对较低,参见图13。

  SIMD的能量细分形成鲜明对比,如图19所示,大约三分之二的能量花在计算上,只有三分之一的能量花在存储器访问上。虽然找到一种计算效率更高的SIMD方法是有意义的,但加速器未来的工作应该集中在减少内存访问所花费的能量上。

  由于严格的能源限制,如Dark Silicon[10,32],越来越多的人一致认为,未来的高性能微体系结构将采用异构多核的形式,即核和加速器的组合。加速器的范围可以从针对某些任务调谐的处理器到诸如H264[14]的类似ASIC的电路,或者能够针对广泛但不是所有任务[12,44] 诸如QsCores[42]的更灵活的加速器,或者用于图像处理[33]的加速器。

  本文中提出的加速器遵循了这种精神,即针对特定但广泛的领域,即这里的机器学习任务。由于机器学习的最新进展,某些类型的神经网络,特别是深度神经网络[25]和卷积神经网络[27],已经在诸如网络搜索[19]、图像分析[31]或语音识别[7]的广泛应用中成为最先进的机器学习技术[26]。

  虽然在过去的二十年里已经研究了许多硬件神经元和神经网络的实现[18],但是硬件神经网络的主要目的是快速建模生物神经网络[20,34],以实现具有数千个连接的神经元。虽然这些神经形态结构中有几个已经应用于计算任务[30,43],但它们所依赖的特定生物启发信息表示(尖峰神经网络)可能无法与最先进的神经网络竞争,尽管这在神经科学和机器学习之间仍然是一个开放的辩论。

  然而,最近,由于应用、机器学习和技术限制的同步趋势,硬件神经网络已经越来越多地被认为是潜在的加速器,要么是用于处理器内非常专用的功能,如分支预测[1],要么是因为它们的容错特性[15,38]。后一种特性也被用来通过硬件神经处理单元[9,11]来交换应用程序的准确性以换取能效[9,11]。

  我们的加速器的重点是大规模的机器学习任务,有数千层神经元和数百万个突触,因此特别强调与记忆的互动。我们的研究不仅与fiRMS以前观察到的专用存储是实现良好性能和功耗的关键[14]相反,而且它还强调,除了在靠近计算运算符的寄存器级别利用局部性[33,38]之外,将内存视为素数阶考虑可以深刻地影响加速器设计。

  前面提到的许多研究都源于架构界。一项对称的努力已经在机器学习领域开始了,在那里,一些研究人员一直在研究加速神经网络处理的硬件设计,特别是对于实时应用。NeuFlow[13]是用于视觉系统的CNN前馈路径的快速和低功耗实现的加速器。它根据卷积层和池层的滑动窗口特性来组织计算和寄存器级存储,但在这方面,它也忽略了来自输入和输出特征映射的大部分一阶局部性。虽然DMA能够执行复杂的访问模式,但它与存储器的相互作用仍然局限于DMA,没有重要的片上存储。Kim等人提出了一种更复杂的架构,尽管其性能与NeuFlow相似。[21]并且由128个SIMD处理器组成,每个处理器16个PE;该体系结构明显更大,并且实现了特定的神经视觉模型(既不是CNN也不是DNNs),但是它可以实现多达10个不同对象的60帧/秒(实时)多对象识别。Maashri等人。[29]还研究了另一种神经网络模型—用于视觉处理的仿生HMAX模型的实现,该模型使用一组布置在交换结构周围的自定义加速器;在文章中,作者提到了跨不同方向的局部性优化,其大致相当于特征映射的HMAX。Chakradhar等人再次接近我们的社区,但只关注CNNs。[3]还研究了CNN在可重构电路上的实现,虽然对局部性开发的重视较少,但为了提高带宽利用率,他们特别注意对CNN进行适当的映射。

9.结论

  在本文中,我们将重点放在机器学习的加速器上,因为加速器的应用范围很广,而且很少有关键的最先进的算法,这为将高效率和广泛的应用范围结合起来提供了难得的机会。由于最先进的CNN和DNN意味着非常大的网络,我们特别关注大规模层的实现。通过仔细利用这些层的局部性属性,并通过引入定制设计的存储结构来利用这些属性,我们展示了在非常小的占地面积内设计能够高性能的机器学习加速器是可能的。我们的测量结果并不局限于加速器结构,它们将主内存传输的性能和能量开销考虑在内;不过,我们表明,在采用普通高速缓存层次结构的128位2 GHz SIMD内核上,可以实现117.87倍的加速比和21.08倍的能耗降低。我们已经得到了65 nm的设计版图。

  除了计划的磁带输出之外,未来的工作还包括改进短层的加速器行为、略微更改NFU以包括一些最新的算法改进,如本地响应标准化、进一步降低主内存传输的影响、调查可伸缩性(特别是增加),以及实施硬件培训。