控制单元为整个计算过程提供了指令控制,负责整个AI Core的运行,指令的分类处理机制如下图所示。
图1 控制单元指令分类处理机制(以分离架构为例)
多条指令从系统内存通过总线接口进入到ICache(Instruction Cache)中,后续的指令执行过程,根据指令的类型,有两种可能:
- 如果指令是Scalar指令,指令会被Scalar单元直接执行。
- 其他指令会被Scalar单元调度到独立的分类序列(Vector指令序列、Cube指令序列、MTE1/MTE2/MTE3指令序列等),然后再被对应的执行单元执行。
同一个指令序列中的指令是按照进入指令序列的顺序执行的,不同指令序列之间可以并行执行,通过多个指令序列的并行执行可以提升整体执行效率。对于并行执行过程中可能出现的数据依赖,通过事件同步模块插入同步指令来控制流水线的同步,提供PipeBarrier、SetFlag/WaitFlag两种API,保证序列内部以及序列之间按照逻辑关系执行。
- PipeBarrier本身是一条指令,用于在序列内部约束执行顺序(虽然指令是顺序执行,但并不意味着后一条指令开始执行时前一条指令执行结束)。PipeBarrier指令可以保证前序指令中所有数据读写全部完成,后序指令才开始执行。
- SetFlag/WaitFlag为两条指令,在SetFlag/WaitFlag的指令中,可以指定一对指令序列的关系,表示两个序列之间完成一组“锁”机制,其作用方式为:
- SetFlag:当前序指令的所有读写操作都完成之后,当前指令开始执行,并将硬件中的对应标志位设置为1。
- WaitFlag:当执行到该指令时,如果发现对应标志位为0,该序列的后续指令将一直被阻塞;如果发现对应标志位为1,则将对应标志位设置为0,同时后续指令开始执行。
Ascend C提供同步控制API,开发者可以使用这类API来自行完成同步控制。需要注意的是,通常情况下,开发者基于编程模型中介绍的编程模型和范式进行编程时不需要关注同步,编程模型帮助开发者完成了同步控制;使用编程模型和范式是我们推荐的编程方式,自行同步控制可能会带来一定的编程复杂度。
但是我们仍然希望开发者可以理解同步的基本原理,便于后续更好的理解设计并行计算程序;同时少数情况需要开发者手动插入同步,您可以通过什么时候需要开发者手动插入同步来了解具体内容。