[AI][昇腾950]MixCore 最高效同步
SetIntraBlock 实现原理与应用1. 概述SetIntraBlock/WaitIntraBlock是 昇腾950 架构中专为Mix-Mode Block1 个 CubeCore 1~2 个 VecCore设计的轻量级核内同步机制用于 CubeCore 与 VecCore 之间的高效协作同步。昇腾950 架构同步层级Level 5: SoC 全局同步 (WFE/SEV) Level 4: 跨 Block 同步 (SetCrossCore / WaitFlagDev) Level 3: Block 内同步 ← SetIntraBlock / WaitIntraBlock (本文) Level 2: 管线间 Buffer 同步 (GetBuf / RlsBuf) [昇腾950 新增加建议使用] Level 1: 管线间事件同步 (SetFlag / WaitFlag) [昇腾950 建议废弃不用] Level 0: 存储屏障 (DSB / DCCI)2. 实现原理2.1 硬件机制每个 Mix-Mode Block 内维护两组 4-bit 计数器CubeCore 端和 VecCore 端各 16 个核心原理为SET 端写入方将对方计数器递增counter[id] 1WAIT 端读取方检查自身计数器若 0 则减 1 并通过若 0 则阻塞等待关键特性SET 递增的是对方的 counter而非自身的。CubeCore (Block X) VecCore (Block X) ┌───────────────────┐ ┌───────────────────┐ │ │ │ │ │ SetIntraBlock ├── ID 3 ──→│ counter[3] 1 │ │ (CubeCore 的 │ │ (VecCore 的 ID 3 │ │ counter 由 │ │ counter 由 │ │ VecCore SET │ │ CubeCore SET │ │ 来递增) │ │ 来递增) │ │ │←─ ID 3 ───┤ SetIntraBlock │ │ counter[3] 1 │ │ │ │ │ │ │ │ WaitIntraBlock │ │ WaitIntraBlock │ │ (若 counter[3]0 │ │ (若 counter[3]0 │ │ 阻塞, 否则 -1) │ │ 阻塞, 否则 -1) │ │ │ │ │ └───────────────────┘ └───────────────────┘2.2 ID 映射规则属性值ID 范围0~15CubeCore 端 16 个VecCore 端 16 个计数器宽度4-bit最大计数值15不可溢出映射关系VecCore SET ID 0~15 → CubeCore counter 0~15反之亦然2.3 指令格式汇编级底层指令// 寄存器版本 SET_INTRA_BLOCK.pipe Xt // Xt[4:0] sync_id WAIT_INTRA_BLOCK.pipe Xt // 立即数版本 SET_INTRA_BLOCKI.pipe #ID // ID: 0~15 WAIT_INTRA_BLOCKI.pipe #ID其中.pipe为管线后缀S标量、M矩阵、V向量、MTE1/MTE2搬运、FFixPipe。C APIinlinevoidset_intra_block(pipe_t pipe,uint8_tflag_id){}inlinevoidwait_intra_block(pipe_t pipe,uint8_tflag_id){}2.4 延迟路径延迟SetIntraBlockSET 端~1-2 cycleWaitIntraBlockWAIT 端计数器 0~1 cycle片内互连总延迟~1-2 cycle不出 Block3. 管线可用性指令SMMTE1MTE2FSetIntraBlock / WaitIntraBlockYYYYY所有管线均可用不受限制。4. 约束与注意事项约束说明仅 Mix-Mode Block只在 CubeCore VecCore 组成的 Mix-Mode Block 中可用计数器不可溢出4-bit 计数器最大值 15溢出将导致异常SET/WAIT 成对使用每次 SET 必须有对应的 WAIT同 ID 单管线等待同一个 ID 不可被多条管线同时等待无 DSB 开销不涉及 DCache 操作无需 DSB/DCCI5. 应用场景5.1 CubeCore↔VecCore 流水线协作最典型的场景CubeCore 完成矩阵计算后通知 VecCore 开始向量后处理VecCore 完成后再通知 CubeCore。// // CubeCore 侧 (.M 管线) // GET_BUFI.M 0, 0 // 获取 L0A buf // ... MMAD 指令 ... RLS_BUFI.M 0, 0 // 释放 L0A buf SET_INTRA_BLOCKI.M 0 // sync_id0, 递增 VecCore 的 counter WAIT_INTRA_BLOCKI.M 0 // 等待 VecCore 的 SET (counter 0) // CubeCore 继续下一步... // // VecCore 侧 (.V 管线) // WAIT_INTRA_BLOCKI.V 0 // 等待 CubeCore 的 SET // ... 向量指令 ... SET_INTRA_BLOCKI.V 0 // sync_id0, 递增 CubeCore 的 counter // VecCore 继续下一步...5.2 单 ID 并发同步在需要多阶段流水线时可使用不同的 sync_id 实现并行通知// CubeCore 使用 ID 0 通知阶段1完成ID 1 通知阶段2完成 SET_INTRA_BLOCKI.M 0 // 通知阶段1 // ... 继续 ... SET_INTRA_BLOCKI.M 0 // 通知阶段2 // VecCore 分别等待两个阶段 WAIT_INTRA_BLOCKI.V 0 // 等待阶段1 // ... 阶段1处理 ... WAIT_INTRA_BLOCKI.V 0 // 等待阶段25.3 循环使用一定要注意连续16次以上的 set_intra_block要么业务上保证 16次的set_intra_block 内必然消费使得计数不超 16要么算法上通过 反向同步等待// CubeCore for(int i0; i 32; i){ copy_l0c_to_ub( ub_addr, l0c_buff,....); set_intra_block( pipe_fixpipe, 0); //通知 aiv0 [id 的范围 0-15] set_intra_block( pipe_fixpipe, 16); //通知 aiv1 if( i 16) { wait_intra_block( pipe_mte2, 0); //让aiv0 消费 wait_intra_block( pipe_mte2, 16); //让aiv0 消费 } } //VecCore AIV0, AIV1 都执 for(int i0; i 32; i){ //等待L0C 的数据到 UB, 然后Vector 计算 wait_intra_block( pipe_v, 0); //aiv1 此时为0 不是 16 vecOp( ub_addr ); if( i 16) { set_intra_block( pipe_v, 0); ///aiv1 此时为0 不是 16 对应cube 为 16 } }6. 性能优势总结特性V220 (旧架构)昇腾950 (新架构)CubeCore↔VecCore 同步方式SSBUF 写入SetIntraBlock 原子计数器单次同步延迟~100 cycle~8 cycle是否需要 DSB必需不需要是否需要 DCCI 失效必需不需要提升—50~100 倍