电子说
在达芬奇架构下,控制单元为整个计算过程提供了指令控制,相当于AI Core的司令部,负责整个AI Core的运行,起到了至关重要的作用。 控制单元的主要组成部分为系统控制模块、指令缓存、标量指令处理队列、指令发射模块、矩阵运算队列、向量运算队列、存储转换队列和事件同步模块,如图3-13中加粗所示。 在指令执行过程中,可以提前预取后续指令,并一次读入多条指令进入缓存,提升指令执行效率。
01 DaVinci架构(总览)
不同于传统的支持通用计算的CPU和GPU,也不同于专用于某种特定算法的专用芯片ASIC,达芬奇架构本质上是为了适应某个特定领域中的常见的应用和算法,通常称之为“特定域架构(Domain Specific Architecture,DSA)”芯片。
昇腾AI芯片的计算核心主要由AI Core构成,负责执行标量、向量和张量相关的计算密集型算子。 AI Core采用了达芬奇架构,其基本结构如图3-2所示,从控制上可以看成是一个相对简化的现代微处理器的基本架构。 它包括了三种基础计算资源:矩阵计算单元(Cube Unit)、向量计算单元(Vector Unit)和标量计算单元(Scalar Unit)。 这三种计算单元分别对应了张量、向量和标量三种常见的计算模式,在实际的计算过程中各司其职,形成了三条独立的执行流水线,在系统软件的统一调度下互相配合达到优化的计算效率。 此外在矩阵计算单元和向量计算单元内部还提供了不同精度、不同类型的计算模式。 AI Core中的矩阵计算单元目前可以支持INT8、INT4和FP16的计算; 向量计算单元目前可以支持FP16和FP32的计算。
为了配合AI Core中数据的传输和搬运,围绕着三种计算资源还分布式的设置了一系列的片上缓冲区,比如用来放置整体图像特征数据、网络参数以及中间结果的输入缓冲区(Input Buffer,IB)和输出缓冲区(Output Buffer,OB),以及提供一些临时变量的高速寄存器单元,这些寄存器单元位于各个计算单元中。 这些存储资源的设计架构和组织方式不尽相同,但目的都是为了更好的适应不同计算模式下格式、精度和数据排布的需求。 这些存储资源和相关联的计算资源相连,或者和总线接口单元(Bus Interface Unit,BIU)相连从而可以获得外部总线上的数据。
在AI Core中,输入缓冲区之后设置了一个存储转换单元(Memory Transfer Unit,MTE)。 这是达芬奇架构的特色之一,主要的目的是为了以极高的效率实现数据格式的转换。 比如前面提到GPU要通过矩阵计算来实现卷积,首先要通过Im2Col的方法把输入的网络和特征数据重新以一定的格式排列起来。 这一步在GPU当中是通过软件来实现的,效率比较低下。 达芬奇架构采用了一个专用的存储转换单元来完成这一过程,将这一步完全固化在硬件电路中,可以在很短的时间之内完成整个转置过程。 由于类似转置的计算在深度神经网络中出现的极为频繁,这样定制化电路模块的设计可以提升AI Core的执行效率,从而能够实现不间断的卷积计算。
AI Core中的控制单元主要包括系统控制模块、标量指令处理队列、指令发射模块、矩阵运算队列、向量运算队列、存储转换队列和事件同步模块。 系统控制模块负责指挥和协调AI Core的整体运行模式,配置参数和实现功耗控制等。
在AI Core中,存储单元为各个计算单元提供转置过并符合要求的数据,计算单元返回运算的结果给存储单元,控制单元为计算单元和存储单元提供指令控制,三者相互协调合作完成计算任务。
02 DaVinci架构(控制单元)
在达芬奇架构下,控制单元为整个计算过程提供了指令控制,相当于AI Core的司令部,负责整个AI Core的运行,起到了至关重要的作用。 控制单元的主要组成部分为系统控制模块、指令缓存、标量指令处理队列、指令发射模块、矩阵运算队列、向量运算队列、存储转换队列和事件同步模块,如图3-13中加粗所示。
在指令执行过程中,可以提前预取后续指令,并一次读入多条指令进入缓存,提升指令执行效率。 多条指令从系统内存通过总线接口进入到AI Core的指令缓存中并等待后续硬件快速自动解码或运算。 指令被解码后便会被导入标量队列中,实现地址解码与运算控制。 这些指令包括矩阵计算指令、向量计算指令以及存储转换指令等。 在进入指令发射模块之前,所有指令都作为普通标量指令被逐条顺次处理。 标量队列将这些指令的地址和参数解码配置好后,由指令发射模块根据指令的类型分别发送到对应的指令执行队列中,而标量指令会驻留在标量指令处理队列中进行后续执行,如图所示。
指令执行队列由矩阵运算队列、向量运算队列和存储转换队列组成。 矩阵计算指令进入矩阵运算队列,向量计算指令进入向量运算队,存储转换指令进入存储转换队列,同一个指令执行队列中的指令是按照进入队列的顺序进行执行的,不同指令执行队列之间可以并行执行,通过多个指令执行队列的并行执行可以提升整体执行效率。
当指令执行队列中的指令到达队列头部时就进入真正的指令执行环节,并被分发到相应的执行单元中,如矩阵计算指令会发送到矩阵计算单元,存储转换指令会发送到存储转换单元。 不同的执行单元可以并行的按照指令来进行计算或处理数据,同一个指令队列中指令执行的流程被称作为指令流水线。
对于指令流水线之间可能出现的数据依赖,达芬奇架构的解决方案是通过设置事件同步模块来统一协调各个流水线的进程。 事件同步模块时刻控制每条流水线的执行状态,并分析不同流水线的依赖关系,从而解决数据依赖和同步的问题。 比如矩阵运算队列的当前指令需要依赖向量计算单元的结果,在执行过程中,事件同步控制模块会暂停矩阵运算队列执行流程,要求其等待向量计算单元的结果。 而当向量计算单元完成计算并输出结果后,此时事件同步模块则通知矩阵运算队列需要的数据已经准备好,可以继续执行。 在事件同步模块准许放行之后矩阵运算队列才会发射当前指令。 在达芬奇架构中,无论是流水线内部的同步还是流水线之间的同步,都是通过事件同步模块利用软件控制来实现的。
在控制单元中还存在一个系统控制模块。 在AI Core运行之前,需要外部的任务调度器来控制和初始化AI Core的各种配置接口,如指令信息、参数信息以及任务块信息等。 这里的任务块是指AI Core中的最小的计算任务粒度。 在配置完成后,系统控制模块会控制任务块的执行进程,同时在任务块执行完成后,系统控制模块会进行中断处理和状态申报。 如果在执行过程中出现了错误,系统控制模块将会把执行的错误状态报告给任务调度器,进而反馈当前AI Core的状态信息给整个昇腾AI芯片系统。
03 DaVinci架构(计算单元)
计算单元是AI Core中提供强大算力的核心单元,相当于AI Core的主力军。 AI Core计算单元主要包含矩阵计算单元、向量计算单元、标量计算单元和累加器,矩阵计算单元和累加器主要完成与矩阵相关的运算,向量计算单元负责执行向量运算,标量计算单元主要负责各类型的标量数据运算和程序的流程控制。
1、矩阵计算单元
上图表示一个矩阵A和另一个矩阵B之间的乘法运算C=A*B,其中M表示矩阵A的行数,K表示矩阵A的列数以及矩阵B的行数,N表示矩阵B的列数。 这个矩阵乘法在CPU如何实现?
该程序需要用到3个循环进行一次完整的矩阵相乘计算,如果在一个单发射的CPU上执行至少需要MKN个时钟周期才能完成,当矩阵非常庞大时执行过程极为耗时。
由于常见的深度神经网络算法中大量的使用了矩阵计算,达芬奇架构中特意对矩阵计算进行了深度的优化并定制了相应的矩阵计算单元来支持高吞吐量的矩阵处理。 通过精巧设计的定制电路和极致的后端优化手段,矩阵计算单元可以用一条指令完成两个16*16矩阵的相乘运算(标记为16^3,也是Cube这一名称的来历),等同于在极短时间内进行了16^3=4096个乘加运算,并且可以实现FP16的运算精度。 如图3-7所示,矩阵计算单元在完成AB=C的矩阵运算时,会事先将矩阵A按行存放在输入缓冲区中,同时将矩阵B按列存放在输入缓冲区中,通过矩阵计算单元计算后得到的结果矩阵C按行存放在输出缓冲区中。 在矩阵相乘运算中,如图3-7所示,矩阵C的第一元素由矩阵A的第一行的16个元素和矩阵B的第一列的16个元素由矩阵计算单元子电路进行16次乘法和15次加法运算得出。 矩阵计算单元中存在256个矩阵计算子电路组成,可以由一条指令并行完成矩阵C的256个元素计算。
2、向量计算单元
AI Core中的向量计算单元主要负责完成和向量相关的运算,能够实现向量和标量,或双向量之间的计算,功能覆盖各种基本和多种定制的计算类型,主要包括FP32、FP16、INT32和INT8等数据类型的计算。
如上图所示,向量计算单元可以快速完成两个FP16类型的向量相加或者相乘。 向量计算单元的源操作数和目的操作数通常都保存在输出缓冲器中。 对向量计算单元而言,输入的数据可以不连续,这取决于输入数据的寻址模式。
向量计算单元可以作为矩阵计算单元和输出缓冲区之间的数据通路和桥梁。 矩阵运算完成后的结果在向输出缓冲区传递的过程中,向量计算单元可以顺便完成在深度神经网络尤其是卷积神经网络计算中常用的ReLU激活函数、池化等功能并实现数据格式的转换。 经过向量计算单元处理后的数据可以被写回到输出缓冲区或者矩阵计算单元中,以等待下一次运算。 所有的这些操作都可以通过软件配合相应的向量单元指令来实现。 向量计算单元提供了丰富的计算功能,也可以实现很多特殊的计算函数,从而和矩阵计算单元形成功能互补,全面完善了AI Core对非矩阵类型数据计算的能力。
3、标量计算单元
标量计算单元负责完成AI Core中与标量相关的运算。 它相当于一个微型CPU,控制整个AI Core的运行。 标量计算单元可以对程序中的循环进行控制,可以实现分支判断,其结果可以通过在事件同步模块中插入同步符的方式来控制AI Core中其它功能性单元的执行流水。 它还为矩阵计算单元或向量计算单元提供数据地址和相关参数的计算,并且能够实现基本的算术运算。 其它复杂度较高的标量运算则由专门的AI CPU通过算子完成。
在标量计算单元周围配备了多个通用寄存器(General Purpose Register,GPR)和专用寄存器(Special Purpose Register,SPR)。 这些通用寄存器可以用于变量或地址的寄存,为算术逻辑运算提供源操作数和存储中间计算结果。 专用寄存器的设计是为了支持指令集中一些指令的特殊功能,一般不可以直接访问,只有部分可以通过指令读写。
AI Core中具有代表性的专用寄存器包括Core ID(用于标识不同的AI Core),VA(向量地址寄存器)以及STATUS(AI Core运行状态寄存器)等。 软件可以通过监视这些专用寄存器来控制和改变AI Core的运行状态和模式。
04 DaVinci架构(存储系统)
AI Core的片上存储单元和相应的数据通路构成了存储系统。 众所周知,几乎所有的深度学习算法都是数据密集型的应用。 对于昇腾AI芯片来说,合理设计的数据存储和传输结构对于最终系统运行的性能至关重要。 不合理的设计往往成为性能瓶颈,从而白白浪费了片上海量的计算资源。 AI Core通过各种类型分布式缓冲区之间的相互配合,为深度神经网络计算提供了大容量和及时的数据供应,为整体计算性能消除了数据流传输的瓶颈,从而支撑了深度学习计算中所需要的大规模、高并发数据的快速有效提取和传输。
1、存储单元
芯片中的计算资源要想发挥强劲算力,必要条件是保证输入数据能够及时准确的出现在计算单元里。 达芬奇架构通过精心设计的存储单元为计算资源保证了数据的供应,相当于AI Core中的后勤系统。 AI Core中的存储单元由存储控制单元、缓冲区和寄存器组成,如图3-11中的加粗显示。 存储控制单元通过总线接口可以直接访问AI Core之外的更低层级的缓存,并且也可以直通到DDR或HBM从而可以直接访问内存。 存储控制单元中还设置了存储转换单元,其目的是将输入数据转换成AI Core中各类型计算单元所兼容的数据格式。 缓冲区包括了用于暂存原始图像特征数据的输入缓冲区,以及处于中心的输出缓冲区来暂存各种形式的中间数据和输出数据。 AI Core中的各类寄存器资源主要是标量计算单元在使用。
所有的缓冲区和寄存器的读写都可以通过底层软件显式的控制,有经验的程序员可以通过巧妙的编程方式来防止存储单元中出现读写冲突而影响流水线的进程。 对于类似卷积和矩阵这样规律性强的计算模式,高度优化的程序可以实现全程无阻塞的流水线执行。
上图中的总线接口单元作为AI Core的“大门”,是一个与系统总线交互的窗口,并以此通向外部世界。 AI Core通过总线接口从外部L2缓冲区、DDR或HBM中读取或者写回数据。 总线接口在这个过程中可以将AI Core内部发出的读写请求转换为符合总线要求的外部读写请求,并完成协议的交互和转换等工作。
输入数据从总线接口读入后就会经由存储转换单元进行处理。 存储转换单元作为AI Core内部数据通路的传输控制器,负责AI Core内部数据在不同缓冲区之间的读写管理,以及完成一系列的格式转换操作,如补零,Img2Col,转置、解压缩等。 存储转换单元还可以控制AI Core内部的输入缓冲区,从而实现局部数据的缓存。
在深度神经网络计算中,由于输入图像特征数据通道众多且数据量庞大,往往会采用输入缓冲区来暂时保留需要频繁重复使用的数据,以达到节省功耗、提高性能的效果。 当输入缓冲区被用来暂存使用率较高的数据时,就不需要每次通过总线接口到AI Core的外部读取,从而在减少总线上数据访问频次的同时也降低了总线上产生拥堵的风险。 另外,当存储转换单元进行数据的格式转换操作时,会产生巨大的带宽需求,达芬奇架构要求源数据必须被存放于输入缓冲区中,才能够进行格式转换,而输入缓冲控制器负责控制数据流入输入缓冲区中。 输入缓冲区的存在有利于将大量用于矩阵计算的数据一次性的被搬移到AI Core内部,同时利用固化的硬件极高的提升了数据格式转换的速度,避免了矩阵计算单元的阻塞,消除了由于数据转换过程缓慢而带来的性能瓶颈。
在神经网络中往往可以把每层计算的中间结果放在输出缓冲区中,从而在进入下一层计算时方便的获取数据。 由于通过总线读取数据的带宽低,延迟大,通过充分利用输出缓冲区就可以大大提升计算效率。
在矩阵计算单元还包含有直接的供数寄存器,提供当前正在进行计算的大小为1616的左、右输入矩阵。 在矩阵计算单元之后,累加器也含有结果寄存器,用于缓存当前计算的大小为1616的结果矩阵。 在累加器配合下可以不断的累积前次矩阵计算的结果,这在卷积神经网络的计算过程中极为常见。 在软件的控制下,当累积的次数达到要求后,结果寄存器中的结果可以被一次性的传输到输出缓冲区中。
AI Core中的存储系统为计算单元提供源源不断的数据,高效适配计算单元的强大算力,综合提升了AI Core的整体计算性能。 与谷歌TPU设计中的统一缓冲区设计理念相类似,AI Core采用了大容量的片上缓冲区设计,通过增大的片上缓存数据量来减少数据从片外存储系统搬运到AI Core中的频次,从而可以降低数据搬运过程中所产生的功耗,有效控制了整体计算的能耗。
达芬奇架构通过存储转换单元中内置的定制电路,在进行数据传输的同时,就可以实现诸如Im2Col或者其它类型的格式转化操作,不光是节省了格式转换过程中的消耗,同时也节省了数据转换的指令开销。 这种能将数据在传输的同时进行转换的指令称为随路指令。 硬件单元对随路指令的支持为程序设计提供了便捷性。
2、数据通路
数据通路指的是AI Core在完成一个计算任务时,数据在AI Core中的流通路径。 前文已经以矩阵相乘为例简单介绍了数据的搬运路径。 图3-12展示了达芬奇架构中一个AI Core内完整的数据传输路径。 这其中包含了DDR或HBM,以及L2缓冲区,这些都属于AI Core核外的数据存储系统。 图中其它各类型的数据缓冲区都属于核内存储系统。
核外存储系统中的数据可以通过LOAD指令被直接搬运到矩阵计算单元中进行计算,输出的结果会被保存在输出缓冲区中。 除了直接将数据通过LOAD指令发送到矩阵计算单元中,核外存储系统中的数据也可以通过LOAD指令先行传入输入缓冲区,再通过其它指令传输到矩阵计算单元中。 这样做的好处是利用大容量的输入缓冲区来暂存需要被矩阵计算单元反复使用的数据。
矩阵计算单元和输出缓冲区之间是可以相互传输数据的。 由于矩阵计算单元容量较小,部分矩阵运算结果可以写入输出缓冲区中,从而提供充裕的空间容纳后续的矩阵计算。 当然也可以将输出缓冲区中的数据再次搬回矩阵计算单元作为后续计算的输入。 输出缓冲区和向量计算单元、标量计算单元以及核外存储系统之间都有一条独立的双向数据通路。 输出缓冲区中的数据可以通过专用寄存器或通用寄存器进出标量计算单元。
值得注意的是,AI Core中的所有数据如果需要向外部传输,都必须经过输出缓冲区,才能够被写回到核外存储系统中。 例如输入缓冲区中的图像特征数据如果需要被输出到系统内存中,则需要先经过矩阵计算单元处理后存入输出缓冲区中,最终从输出缓冲区写回到核外存储系统中。 在AI Core中并没有一条从输入缓冲区直接写入到输出缓冲区的数据通路。 因此输出缓冲区作为AI Core数据流出的闸口,能够统一的控制和协调所有核内数据的输出。
达芬奇架构数据通路的特点是多进单出,数据流入AI Core可以通过多条数据通路,可以从外部直接流入矩阵计算单元、输入缓冲区和输出缓冲区中的任何一个,流入路径的方式比较灵活,在软件的控制下由不同数据流水线分别进行管理。 而数据输出则必须通过输出缓冲区,最终才能输出到核外存储系统中。
这样设计的理由主要是考虑到了深度神经网络计算的特征。 神经网络在计算过程中,往往输入的数据种类繁多并且数量巨大,比如多个通道、多个卷积核的权重和偏置值以及多个通道的特征值等,而AI Core中对应这些数据的存储单元可以相对独立且固定,可以通过并行输入的方式来提高数据流入的效率,满足海量计算的需求。 AI Core中设计多个输入数据通路的好处是对输入数据流的限制少,能够为计算源源不断的输送源数据。 与此相反,深度神经网络计算将多种输入数据处理完成后往往只生成输出特征矩阵,数据种类相对单一。 根据神经网络输出数据的特点,在AI Core中设计了单输出的数据通路,一方面节约了芯片硬件资源,另一方面可以统一管理输出数据,将数据输出的控制硬件降到最低。
综上,达芬奇架构中的各个存储单元之间的数据通路以及多进单出的核内外数据交换机制是在深入研究了以卷积神经网络为代表的主流深度学习算法后开发出来的,目的是在保障数据良好的流动性前提下,减少芯片成本、提升计算性能、降低控制复杂度。
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !