一、前端调度系统:任务进入 GPU 的"第一站"
MUSA 前端调度系统是连接主机端(CPU)与设备端(GPU)的枢纽,核心价值是把用户抽象的并行代码任务,转化为 GPU 硬件可高效执行的任务,实现有序分发、依赖管控与负载均衡。它由三个单元协作组成:
- Command Fetcher:接收与预处理单元,从主机接口接收 CPU 发送的 Command Queue,依次解析队列中的各项任务
- Command Processor:对不同命令类型执行差异化处理,负责把 KERNEL 命令按 X/Y/Z 维度拆解为多个独立 Block,分发到不同 MPC
- Task Controller:位于 MPX 内部,负责 Block 在两个 MP 间的调度,将连续 32 个 Thread 组成一个 Task 送 MP 执行
Command Queue 由数据头和一系列数据块构成,主要支持 6 种命令:
| 命令 | 作用 |
|---|---|
| KERNEL | 最核心的命令,在 GPU 上并行执行 MUSA 程序,需指定 Grid/Block/Thread 参数与输入参数信息 |
| CALL / RETURN | 跳转命令,实现命令队列内的跳转与子程序调用/返回 |
| SEMAPHORE | 信号量,用于多个 KERNEL 之间的依赖管理 |
| CACHE_FLUSH | Cache 刷写和失效操作 |
| FINISH | 结束标志 |
Kernel 依赖处理与同步的三层机制
前端调度通过三层硬件机制保证任务执行的正确性与有效性:
- 信号量(Semaphore)机制——Kernel 间依赖:本质是显存中分配的整数变量。当 Kernel A 需等待 Kernel B 时,在 Kernel B 之后配置
atomicAdd(semaphore_addr, 1)的 SEMAPHORE SIGNAL 命令,在 Kernel A 之前配置 SEMAPHORE WAIT 命令(等待 semaphore_addr 达到预期值)。这一机制将任务依赖转化为硬件可直接监控的内存操作,实现异步高效同步 - 缓存同步——CACHE_FLUSH:执行缓存刷写与失效前,需等待所有已发送的 Kernel 完成,避免缓存数据未同步导致后续任务读脏数据
- 全局同步——FINISH:Command Queue 的结束标志,等待队列中所有命令与已分发 Block 执行完毕,再向主机上报任务结束中断
二、MUSA 计算体系:MP 与 MPE 的模块化设计
MUSA 计算体系采用分层与模块化的组织方式,自上而下是三级结构:
MPC(MUSA Processor Cluster,处理器簇)
└── MP(MUSA Processor,流处理器核 = 核心计算单元)
└── MPE(MUSA Processor Element,SIMT 指令执行与算术运算的基本结构单元)
└── 128 个 SIMT 核心 + TCE + LSU + Tex
MP(MUSA Processor)是摩尔线程自研架构中的流处理器核,作为核心计算单元。一个 MP 内部通过 4 个相同结构的 MPE 核心组和一组外部扩展单元共同构筑算力矩阵:
- 通用向量算力:集成 128 个 SIMT 核心,包括 FP32、INT32、FP64 ALU 和特殊函数单元(SFU)
- AI 张量引擎(TCE,Tensor Compute Engine):专门针对深度学习矩阵运算设计的硬件加速单元
- 访存子系统:配备 32 个数据加载/存储单元(LSU),并拥有 8 个纹理处理单元(Tex)
- 存储资源:内置通用数据寄存器(Vector Reg)及共享存储空间(Shared Memory,ShMem)
MPE(MUSA Processor Element)是 MP 的子级单位,是 GPU 计算处理器最小组成单元。每个 MPE 拥有独立的控制流处理能力(线程束调度控制器 WM、指令调度发射器 ICtrl、局部指令缓存 L0I),确保 SIMT 模式下的线程级并行。MPE 内部的运算单元包括:
- FP32 ALU:处理浮点 FMA(融合乘积累加)或半精度(FP16)FMA
- INT32 ALU:整型运算或位运算
- FP64 ALU:双精度浮点运算
- SFU(特殊函数单元):快速计算超越函数(RCP、RSQ、SQRT、EXP、LOG2、SIN、COS 等)
- sALU(标量 ALU):专门处理标量指令
三、线程组织与调度:线程束调度器 + 指令调度器
MUSA 通过三维线程组织结构,将大规模计算任务拆分为可调度的线程块,并以线程束(Warp)为执行粒度。线程束是 SIMT 架构的基本执行单元,由 32 个独立线程打包组成,包含线程掩码、线程束状态、32 线程的取指 PC 等核心信息。
线程束调度状态机(5 状态)
空闲状态 ──→ 就绪状态 ──→ 执行状态
↑ │
└── 阻塞状态 ←─┘
│
结束状态 ──→ 空闲状态
- 空闲状态:线程束无效,上游可下发新的线程束
- 就绪状态:线程束无资源阻挡,可等待调度
- 执行状态:线程束向指令调度器发射线程束 ID 与对应 PC,启动取指
- 阻塞状态:因特定条件未满足(如指令缓存未命中、数据依赖未解除)暂停调度,避免无效重试
- 结束状态:解析并结束指令,线程束准备释放资源
指令调度器是影响线程束执行效率并控制各流水线指令发射的关键组件。一个周期内,指令调度器支持连续发射两条指令(一条 ALU 指令和一条非 ALU 指令),同时支持线程束内连续发射。其四大核心功能:指令取指、多发射逻辑、数据依赖优化(依赖计数器管理有序与乱序)、分支发散优化(用线程掩码+Predicate 寄存器降低分支发散对调度效率的影响)。
四、MUSA 存储体系:分层设计的延迟与带宽权衡
MUSA 存储体系采用分层设计,从计算核心到外部设备形成明确的多级层次。各层级的延迟数量级与带宽数量级差异显著:
| 存储层级 | 典型延迟 | 典型带宽 | 说明 |
|---|---|---|---|
| 寄存器 | 几个周期(数纳秒) | 数十 TB/s | 每个线程私有,速度最快,数量有限 |
| 共享存储器 | ~10–20 周期(~10ns) | ~10 TB/s | 每个 MP 内部共享 |
| L1 缓存 | ~20–50 周期 | ~10 TB/s | 全局内存访问的一级缓存,MP 内共享 |
| L2 缓存 | ~50–200 周期 | 数 TB/s | MPC 内部数据共享 |
| L3 缓存 | ~200–300 周期 | 数 TB/s | 全 GPU 数据共享,减少显存访问 |
| 显存 | ~300–800 周期 | 数百 GB/s–数 TB/s | 容量大,延迟高 |
| 主机内存(PCIe) | ~1–10μs | 数十 GB/s | 仅用于 CPU-GPU 数据交换 |
| 卡间通信(MTLink) | 数百纳秒–1μs | 数百 GB/s | 仅用于 GPU 之间的数据交换 |
几个关键设计要点:
- 寄存器溢出:不是数值溢出,而是线程使用变量超出物理寄存器限制,硬件把部分数据放进私有寄存器(显存中开辟的独立空间),用时间换空间——这会导致性能下降,是优化时要重点规避的
- 共享存储器 Bank:通常有 32 或 64 个 Bank,每 Bank 32 比特宽,单周期内可并行访问多个 Bank,访问速度接近寄存器;同一 Bank 不同地址的访问会发生冲突
- 地址交织:显存被划分为多个独立通道,每通道配备 L3 缓存片与内存控制器。例如 16 个显存通道搭配 1KB 交织粒度,每 1KB 数据依次落到不同通道,大量线程访问连续数据时可充分利用所有通道带宽
- MTLink:MUSA 引入 MTLink 实现高速卡间通信,替代传统 PCIe 和 PCIe Switch 方式,专门用于 GPU 之间的数据交换
五、张量核心架构:TME + TCE + ASYNC
针对 AI 场景的海量张量计算需求,MUSA 增设张量子系统,是 AI 算力增强的核心模块。它由三部分组成:
1. TME(张量搬运)
TME 负责在全局内存和共享存储器之间搬运张量数据,最大支持五维张量,支持三种模式:
- TILE 模式:最基本的模式,常见的 GEMM Kernel 与 Convolution Kernel 中的 weight 数据都用它访问。通过指定起始坐标和各维度大小,TME 读取张量描述符计算元素地址并搬运
- IM2COL 模式:用矩阵乘实现卷积的算法,硬件方式实现避免软件大量地址计算。张量以 NDHWC 格式存放,硬件可在单次访问周期内读取多个通道数据
- Swizzle 模式:把共享存储器中同一行数据的位置进行变换,将同一 Bank 中不同行的数据分散到不同 Bank,避免 Bank 冲突增大带宽(由 SG、SS、SL 三个参数控制)
2. TCE(Tensor Compute Engine)
传统 SIMD/SIMT 单元计算矩阵乘积用 FMA 向量单元,随算力需求增长带宽压力增大,因此增加 TCE 通过线程束内以及线程束间数据共享满足高算力带宽需求。TCE 支持两种模式:
- WMMA:线程束级别的 MMA 指令,矩阵 A、B 数据来自寄存器且在线程束内复用
- SQMMA:4 个线程束(来自不同 MPE)组成一组,4 个 ALU 之间数据共享,减少对寄存器的带宽需求。矩阵 A 可来自寄存器(便于 Kernel 融合)或共享存储器,矩阵 B 来自共享存储器
3. ASYNC(异步事务屏障)
传统线程间同步用 sync 指令会阻塞当前线程直到 block 内所有线程都执行了该指令。ASYNC 在 sync 基础上增加异步屏障,将 sync 拆分为 arrive 和 wait 两条独立指令:arrive 可提前执行,然后可以在 arrive 和 wait 之间执行一些无关指令,提高硬件利用率。当生产者(如 TME 搬运)完成后执行 arrive,需要使用数据时执行 wait。这是构建软件流水线(Software Pipelining)的硬件基础。
六、Step-by-Step:用架构知识指导一次优化决策
掌握了硬件架构后,我们把它落到一个实际优化决策上。假设你在 MTT S5000 上跑一个 GEMM Kernel 性能不达标,按架构逐层排查:
# 伪代码:GEMM 优化决策树(基于第 2 章架构知识)
# 第 1 步:确认 Occupancy —— 是否用满 MP
# 线程块中线程数 <= 1024(资源限制),寄存器/共享存储是否成为瓶颈
def check_occupancy(regs_per_thread, smem_per_block):
# 寄存器溢出会走私有寄存器(显存),延迟骤增
if regs_per_thread > REG_LIMIT:
return "降低寄存器使用,或拆分 Kernel"
if smem_per_block > SMEM_LIMIT:
return "减小 tile 尺寸"
return "Occupancy OK"
# 第 2 步:访存优化 —— 是否命中地址交织与合并访存
# 连续线程访问连续地址,充分利用显存多通道带宽
def check_memory_access(access_pattern):
if access_pattern == "strided":
return "改为合并访存(coalesced),利用 1KB 交织粒度"
return "访存 OK"
# 第 3 步:共享存储 Bank 冲突 —— 是否需要 Swizzle
def check_bank_conflict(smem_layout):
if has_bank_conflict(smem_layout):
return "用 TME Swizzle 模式打散 Bank"
return "无 Bank 冲突"
# 第 4 步:是否用上 TCE —— GEMM 应走 SQMMA 而非 FMA
def check_tensor_engine(kernel):
if kernel.uses == "FMA_vector":
return "改用 TCE SQMMA,A 来自共享存储,B 来自共享存储"
return "已用 TCE"
# 第 5 步:软件流水线 —— 用 ASYNC arrive/wait 重叠搬运与计算
def check_pipeline(kernel):
if not kernel.overlaps_load_compute:
return "用 ASYNC 屏障重叠 TME 搬运与 TCE 计算"
return "流水线 OK"
这个决策树正好对应教材第 8 章的 GEMM 优化案例:Occupancy 调控 → 合并/向量化访存 → 减少 Bank 冲突 → 用 TCE → 软件流水线。第 2 章的架构知识是"为什么这样优化",第 8 章的案例是"具体怎么优化"。
七、本章知识与后续课程
- m11-l3(第 3 章):编程模型——把本章的硬件抽象成 Kernel/Context/Stream 编程接口
- m11-l4(第 4 章):软件架构——muDNN/muBLAS 等库如何封装本章的 TCE/TME 硬件能力
- m8 模块:LLM 推理优化——本章的存储层次与张量核心是理解 Flash Attention、P/D 分离的硬件基础
- m6 模块:CUDA 迁移——MUSA 与 CUDA 的架构对应关系(MP↔SM、MPE↔子核、TCE↔Tensor Core)