cann/asc-devkit核间同步关键特性
关键特性说明
【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit
如图1所示,本章节将配合时序图介绍CrossCoreSetFlag和CrossCoreWaitFlag配合使用时支持的四种同步控制模式各自实现的原理。
- 模式0:AI Core核间的同步控制。对于AIC全核场景,同步所有的AIC核,直到所有的AIC核都执行到CrossCoreSetFlag时,CrossCoreWaitFlag后续的指令才会执行;对于AIV全核场景,同步所有的AIV核,直到所有的AIV核都执行到CrossCoreSetFlag时,CrossCoreWaitFlag后续的指令才会执行。
- 模式1:AI Core内部,AIV核之间的同步控制。如果两个AIV核都运行了CrossCoreSetFlag,CrossCoreWaitFlag后续的指令才会执行。
- 模式2:AI Core内部,AIC与AIV之间的同步控制。在AIC核执行CrossCoreSetFlag之后,两个AIV上CrossCoreWaitFlag后续的指令才会继续执行;两个AIV都执行CrossCoreSetFlag后,AIC上CrossCoreWaitFlag后续的指令才能执行。
- 模式4:AI Core内部,AIC与单个AIV之间的同步控制。AIV0与AIV1可单独触发AIC等待。
图1同步控制模式示意图

下述同步特性均以该场景配置为例:每个AI Core包含1个AIC和M个AIV,共启动N个AI Core,即存在N个AIC和M * N个AIV。
多AI Core中AIC或者AIV全核同步
多AI Core中AIC或者AIV全核同步需要配套使用模式0的CrossCoreSetFlag.md)和CrossCoreWaitFlag.md)接口。该场景可细分为两类:
N个AI Core中的N个AIC进行全核同步。
当N个AIC都执行完CrossCoreSetFlag时,每个AIC对应flagId的计数器增加1。若AIC该flagId的计数器为非0,被CrossCoreWaitFlag所阻塞的所有指令才会执行下去,该flagId的计数器减去1。
对于每个AIC,CrossCoreSetFlag和CrossCoreWaitFlag都必须配对使用。
N个AI Core中的M * N个AIV进行全核同步。
当M * N个AIV都执行完CrossCoreSetFlag时,每个AIV核对应flagId的计数器增加1。若AIV该flagId的计数器为非0,被CrossCoreWaitFlag所阻塞的所有指令才会执行下去,该flagId的计数器减去1。
对于每个AIV,CrossCoreSetFlag和CrossCoreWaitFlag都必须配对使用。
// 每个核都应该有类似如下的成对调用CrossCoreSetFlag和CrossCoreWaitFlag // modeId必须配置为0, pipe要一致,flagId要一致 AscendC::CrossCoreSetFlag<0, PIPE_M>(0); // 待前置PIPE_M流水任务完成后,通知调度模块 AscendC::CrossCoreWaitFlag(0); // 直到所有AIC都完成前置PIPE_M流水,调度模块更新flagId=0的计数器后,解除阻塞。
以图1为例,演示N=2时,2个AI Core中的2个AIC进行全核同步。
AIC 1中在执行CrossCoreWaitFlag后,此时AIC 1 flagId=0的计数器为0,后续所有指令全部被阻塞,需要等到2个AIC核均执行完CrossCoreSetFlag。
AIC 2的CrossCoreSetFlag执行完后,此时调度模块感知到2个AIC均已执行完CrossCoreSetFlag,因此所有AIC各自的flagId=0的计数器值增加为1。AIC 1和AIC 2检测到各自对应的flagId=0的计数器变为1,都解除阻塞,继续执行后续指令,并且将计数器值减去1。
图1模式0:多AI Core中AIC全核同步

单AI Core中AIV全核同步
该场景需要配套使用模式1的CrossCoreSetFlag.md)和CrossCoreWaitFlag.md)接口。
1个AI Core中的M个AIV进行全核同步。当M个AIV全部都执行完CrossCoreSetFlag时,每个AIV对应flagId的计数器增加1。若AIV该flagId的计数器为非0,被CrossCoreWaitFlag所阻塞的所有指令才会执行下去,该flagId的计数器减去1。对于每个AIV,CrossCoreSetFlag和CrossCoreWaitFlag都必须配对使用。
[!CAUTION]注意 该模式中,不同AI Core的AIV核之间不会互相影响同步。
// 每个AIV都应该有类似如下的成对调用CrossCoreSetFlag和CrossCoreWaitFlag // modeId必须配置为1, pipe要一致,flagId要一致 AscendC::CrossCoreSetFlag<1, PIPE_MTE3>(0); // 待前置PIPE_MTE3流水任务完成后,通知调度模块 AscendC::CrossCoreWaitFlag(0); // 直到该AI Core中的所有AIV都完成前置PIPE_MTE3流水,调度模块更新flagId=0的计数器后,解除阻塞。以图2为例,演示M=2时,1个AI Core中的2个AIV进行全核同步。
AIV 1-1中在执行CrossCoreWaitFlag后,此时AIV 1-1 flagId=0的计数器为0,后续所有指令全部被阻塞,需要等到2个AIV均执行完CrossCoreSetFlag。
AIV 1-2的CrossCoreSetFlag执行完后,此时调度模块感知到2个AIV均已执行完CrossCoreSetFlag,因此将AIV 1-1和AIV 1-2各自的flagId=0的计数器值增加为1。AIV 1-1和AIV 1-2检测到各自对应的flagId=0的计数器变为1,都解除阻塞,继续执行后续指令,并且将计数器值减去1。
图2模式1:单AI Core中AIV全核同步

单AI Core中AIC与AIV全核同步
单AI Core中AIC与AIV全核同步需要配套使用模式2的CrossCoreSetFlag.md)和CrossCoreWaitFlag.md)接口。该场景可细分为两类:
1个AI Core中的AIC执行CrossCoreSetFlag,对应的M个AIV都执行CrossCoreWaitFlag。
当AIC执行完CrossCoreSetFlag时,M个AIV对应flagId的计数器增加1。若AIV该flagId的计数器为非0,则解除AIV的阻塞,CrossCoreWaitFlag后的指令继续发射,该flagId的计数器减去1。
总计AIC 1次调用CrossCoreSetFlag,对应M个AIV各1次CrossCoreWaitFlag才算配对使用。
1个AI Core中的M个AIV都执行CrossCoreSetFlag,对应的AIC执行CrossCoreWaitFlag。
当M个AIV全都执行完CrossCoreSetFlag时,AIC对应flagId的计数器增加1。若AIC该flagId的计数器为非0,则解除AIC的阻塞,CrossCoreWaitFlag后的指令继续发射,该flagId的计数器减去1。
总计M个AIV各1次CrossCoreSetFlag,对应AIC 1次调用CrossCoreWaitFlag才算配对使用。
// AIC和AIV都应该有类似如下的成对调用CrossCoreSetFlag和CrossCoreWaitFlag // modeId必须配置为2, pipe要一致,flagId要一致 if ASCEND_IS_AIV { AscendC::CrossCoreSetFlag<2, PIPE_MTE3>(0); // 待前置PIPE_MTE3流水任务完成后,通知调度模块。必须要所有AIV都执行。 } if ASCEND_IS_AIC { AscendC::CrossCoreWaitFlag(0); // 直到该AI Core中的所有AIV都完成前置PIPE_MTE3流水,调度模块更新flagId=0的计数器后,AIC解除阻塞。 }以图3为例,演示M=2时,1个AI Core中AIV与AIC进行同步(AIV发起CrossCoreSetFlag)。
AIC 1中在执行CrossCoreWaitFlag后,此时AIC 1 flagId=0的计数器为0,后续所有指令全部被阻塞,需要等到2个AIV均执行完CrossCoreSetFlag。
当AIV 1-2的CrossCoreSetFlag在Vector指令1执行完后,前置PIPE_V的指令全部完成,CrossCoreSetFlag执行完成,但是此时AIV 1-1未执行CrossCoreSetFlag。因此AIC 1 flagId=0的计数器还是为0,AIC的所有指令依然被阻塞。
当AIV 1-1的Vector指令1、2全部执行完毕后,前置PIPE_V的指令全部完成,CrossCoreSetFlag生效。此时调度模块感知到2个AIV均已执行完CrossCoreSetFlag,因此将AIC 1 flagId=0的计数器值增加为1。AIC 1检测到对应的flagId=0的计数器变为1,则AIC 1核解除阻塞,继续执行后续指令Matrix指令2,并且将计数器值减去1。
图3模式2:单AI Core中AIC与AIV全核同步(AIV进行CrossCoreSetFlag)
"?utm_source=gitcode_repo_files)
单AI Core中AIC与单个AIV同步
单AI Core中AIC与单个AIV同步需要配套使用模式4的CrossCoreSetFlag.md)和CrossCoreWaitFlag.md)接口。该场景可细分为两类:
1个AI Core中的AIC执行CrossCoreSetFlag,对应的AIV执行CrossCoreWaitFlag。
当AIC执行完CrossCoreSetFlag时,AIV对应flagId的计数器增加1。若AIV该flagId的计数器为非0,则解除AIV的阻塞,CrossCoreWaitFlag后的指令继续发射,该flagId的计数器减去1。
总计AIC 1次调用CrossCoreSetFlag,单个AIV完成一次CrossCoreWaitFlag才算配对使用。
1个AI Core中的1个AIV执行CrossCoreSetFlag,对应的AIC执行CrossCoreWaitFlag。
当AIV执行完CrossCoreSetFlag时,AIC对应flagId的计数器增加1。若AIC该flagId的计数器为非0,则解除AIC的阻塞,CrossCoreWaitFlag后的指令继续发射,该flagId的计数器减去1。
总计单个AIV 1次CrossCoreSetFlag,对应AIC 1次调用CrossCoreWaitFlag才算配对使用。
// AIC和AIV都应该有类似如下的成对调用CrossCoreSetFlag和CrossCoreWaitFlag // modeId必须配置为4,flagId要一致 if ASCEND_IS_AIV { if (blockIdx % 2 == 0) { AscendC::CrossCoreSetFlag<4, PIPE_MTE3>(0); // 待AIV0上前置PIPE_MTE3流水任务完成后,通知调度器。对于flagId,AIV0上的0-15对应AIC上的0-15。 } if (blockIdx % 2 == 1) { AscendC::CrossCoreSetFlag<4, PIPE_MTE3>(0); // 待AIV1上前置PIPE_MTE3流水任务完成后,通知调度器。对于flagId,AIV1上的0-15对应AIC上的16-31。 } } if ASCEND_IS_AIC { AscendC::CrossCoreWaitFlag<4, PIPE_FIX>(0); // 阻塞后续PIPE_FIX流水指令,直到该AI Core中的AIV0都完成前置PIPE_MTE3流水,调度器更新flagId=0的计数器后,AIC解除阻塞 ... AscendC::CrossCoreWaitFlag<4, PIPE_FIX>(16); // 阻塞后续PIPE_FIX流水指令,直到该AI Core中的AIV1都完成前置PIPE_MTE3流水,调度器更新flagId=16的计数器后,AIC解除阻塞 ... }以图4为例,演示M=2时,1个AI Core中AIV1与AIC进行同步(AIV1-2发起CrossCoreSetFlag)。
AIC 1中在执行CrossCoreWaitFlag后,此时AIC 1 flagId=0的计数器为0,后续所有指令全部被阻塞,需要等到1个AIV执行完CrossCoreSetFlag。
- AIV 1-1不需要执行CrossCoreSetFlag。
- AIV 1-2的PIPE_MTE3指令全部执行完毕后,CrossCoreSetFlag生效。此时调度模块感知1个AIV已执行完CrossCoreSetFlag,因此将AIC 1 flagId=0的计数器值增加为1。AIC 1检测到对应的flagId=0的计数器变为1,则AIC 1核解除阻塞,继续执行后续PIPE_FIX的指令,并且将计数器值减去1。
图4模式4:单AI Core中AIC与单个AIV同步(AIV进行CrossCoreSetFlag)
"?utm_source=gitcode_repo_files)
【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考