基本架构
如下图所示,基于Ascend C开发的算子运行在AI Core上。Ascend C编程模型基于AI Core硬件架构的抽象进行介绍,了解硬件架构能够帮助开发者更好的理解编程模型;对于需要完成高性能编程的深度开发者,更需要了解硬件架构相关知识,最佳实践中很多内容都以本章为基础进行介绍。
硬件架构根据Cube计算单元和Vector计算单元是否同核部署分为耦合架构和分离架构两种。如下产品型号对应的处理器架构模式如下:
Atlas 推理系列产品 :耦合架构Atlas 训练系列产品 :耦合架构Atlas A2 训练系列产品 /Atlas 800I A2 推理产品 /A200I A2 Box 异构组件:分离架构Atlas A3 训练系列产品 /Atlas A3 推理系列产品 :分离架构Atlas 200I/500 A2 推理产品 :耦合架构
本节以
AI Core负责执行标量、向量和张量相关的计算密集型算子,包括以下组成部分:
- 计算单元:包括Cube(矩阵)计算单元、Vector(向量)计算单元和Scalar(标量)计算单元。
- 存储单元:包括L1 Buffer、L0A Buffer、L0B Buffer、L0C Buffer、Unified Buffer、BiasTable Buffer、Fixpipe Buffer等专为高效计算设计的存储单元。
- 搬运单元:包括MTE1、MTE2、MTE3和FixPipe,用于数据在不同存储单元之间的高效传输。
本架构中AI Core分为AIC(AI Cube)和AIV(AI Vector)两个独立的核,分别用于矩阵计算和向量计算。
本章节首先阐述计算单元、存储单元和搬运单元的基本功能与结构,随后通过典型的数据流和控制流示例,帮助开发者深入理解硬件架构的工作原理。
计算单元
计算单元是AI Core中提供强大算力的核心单元,包括三种基础计算单元:Cube(矩阵)计算单元、Vector(向量)计算单元和Scalar(标量)计算单元,完成AI Core中不同类型的数据计算。
- Cube
Cube计算单元负责执行矩阵运算,以float16数据类型为例,Cube每次执行可完成两个float16类型的16x16矩阵的乘法操作。如下图所示,高亮部分为Cube计算单元及其访问的存储单元,其中L0A存储左矩阵,L0B存储右矩阵,L0C存储矩阵乘的结果和中间结果。
图1 Cube计算单元数据访问 - Vector
Vector负责执行向量运算。向量计算单元执行向量指令,类似于传统的单指令多数据(Single Instruction Multiple Data,SIMD)指令,每个向量指令可以完成多个操作数的同一类型运算。向量计算单元可以快速完成两个float16类型的向量相加或者相乘。向量指令支持多次迭代执行,也支持对带有间隔的向量直接进行运算。
如下图所示,Vector所有计算的源数据以及目标数据都要求存储在Unified Buffer中,Vector指令的首地址和操作长度有对齐要求,通常要求32B对齐,具体对齐要求参考API的约束描述。
图2 Vector计算单元数据访问
- Scalar
Scalar负责各类型的标量数据运算和程序的流程控制。功能上可以看做一个小CPU,完成整个程序的循环控制、分支判断、Cube/Vector等指令的地址和参数计算以及基本的算术运算,并且可以通过在事件同步模块中插入同步符的方式来控制AI Core中其他执行单元的流水。相对于Host CPU,AI Core中的Scalar计算能力较弱,重点用于发射指令,所以在实际应用场景中应尽量减少Scalar计算,比如性能调优时尽量减少if/else等分支判断及变量运算。
如下图所示:Scalar执行标量运算指令时,执行标准的ALU(Arithmetic Logic Unit)语句,ALU需要的代码段和数据段(栈空间)都来自于GM,ICache(Instruction Cache)用于缓存代码段,缓存大小与硬件规格相关,比如为16K或32K,以2K为单位加载;DCache(Data Cache)用于缓存数据段,大小也与硬件规格相关,比如为16K,以cacheline(64Byte)为单位加载。考虑到核内访问效率最高,应尽量保证代码段和数据段被缓存在ICache和DCache,避免核外访问; 同时根据数据加载单位不同,编程时可以考虑单次加载数据大小,来提升加载效率。例如在DCache加载数据时,当数据内存首地址与cacheline(64Byte)对齐时,加载效率最高。
图3 Scalar对指令和数据的访问硬件提供L2Cache用于缓存访问GM的数据(包括代码段、数据段),以此加快访问速度,提高访问效率。核外L2Cache以cacheline为单位加载数据,根据硬件规格不同,cacheline大小不同(128/256/512Byte等)。
存储单元和搬运单元
AI处理器中的计算资源要想发挥强劲算力,必要条件是保证输入数据能够及时准确地出现在计算单元中,需要精心设计存储系统,保证计算单元所需的数据供应。
如下图所示:AI Core中包含多级内部存储,AI Core需要把外部存储中的数据加载到内部存储中,才能完成相应的计算。AI Core的主要内部存储包括:L1 Buffer(L1缓冲区),L0 Buffer(L0缓冲区),Unified Buffer(统一缓冲区)等。为了配合AI Core中的数据传输和搬运,AI Core中还包含MTE(Memory Transfer Engine,数据传递引擎)搬运单元,在搬运过程中可执行随路数据格式/类型转换。


典型的数据流
- Vector计算典型的数据流如下:
GM → UB → Vector → UB → GM
- Cube计算典型的数据流如下:
- GM →L1→L0A/L0B →Cube →L0C→FixPipe→GM
- GM →L1→L0A/L0B →Cube →L0C→FixPipe→L1
典型的指令流
多条指令从系统内存通过总线接口进入到ICache(Instruction Cache)中,后续的指令执行过程,根据指令的类型,有两种可能:
- 如果指令是Scalar指令,指令会被Scalar单元直接执行。
- 其他指令会被Scalar单元调度到独立的分类序列(Vector指令序列、Cube指令序列、MTE1/MTE2/MTE3指令序列等),然后再被对应的执行单元执行。

- PipeBarrier本身是一条指令,用于在序列内部约束执行顺序(虽然指令是顺序执行,但并不意味着后一条指令开始执行时前一条指令执行结束)。PipeBarrier指令可以保证前序指令中所有数据读写全部完成,后序指令才开始执行。
- SetFlag/WaitFlag为两条指令,在SetFlag/WaitFlag的指令中,可以指定一对指令序列的关系,表示两个序列之间完成一组“锁”机制,其作用方式为:
- SetFlag:当前序指令的所有读写操作都完成之后,当前指令开始执行,并将硬件中的对应标志位设置为1。
- WaitFlag:当执行到该指令时,如果发现对应标志位为0,该序列的后续指令将一直被阻塞;如果发现对应标志位为1,则将对应标志位设置为0,同时后续指令开始执行。
Ascend C提供同步控制API,开发者可以使用这类API来自行完成同步控制。需要注意的是,通常情况下,开发者基于编程模型中介绍的编程模型和范式进行编程时不需要关注同步,编程模型帮助开发者完成了同步控制;使用编程模型和范式是我们推荐的编程方式,自行同步控制可能会带来一定的编程复杂度。
但是我们仍然希望开发者可以理解同步的基本原理,便于后续更好的理解设计并行计算程序;同时少数情况需要开发者手动插入同步,您可以通过什么时候需要开发者手动插入同步来了解具体内容。