AICore:达芬奇架构的心脏怎么跳 本文基于昇腾CANN和昇腾NPU围绕 AICore 执行架构技术展开。达芬奇架构是昇腾NPU的计算核心每个 Ascend 910 上有 32 个独立的达芬奇 Core。每个 Core 内部有三样东西一个 Cube Unit矩阵乘加、两个 Vector Unit逐元素运算、一个 Scalar Unit标量控制。三者不是串行排队——它们在同一个 cycle 内可以并行工作。这就是 AICore 最核心的设计理念Cube 算着当前 Tile 的 GEMMVector 同时处理上一个 Tile 的 ActivationScalar 准备下一个 Tile 的地址和循环控制。三级流水并行。AICore 内部架构AICore 内部结构单 Core ┌─────────────────────────────────────────┐ │ Scalar Unit │ │ 地址计算 │ 循环控制 │ 条件判断 │ └─────────────────────────────────────────┘ │ │ ┌─────┴─────┐ ┌────┴─────┐ │ Cube Unit │ │ Vector │ │ │ │ Unit ×2 │ │ 16×16×16 │ │ │ │ FP16 MAC │ │ 256 FP16 │ │ per cycle │ │ per cycle│ └───────────┘ └──────────┘ │ │ ┌─────┴────────────────────┴─────┐ │ L1 Buffer (192KB) │ │ L0A (64KB) │ L0B (64KB) │ │ L0C (64KB) │ └─────────────────────────────────┘ │ DDR / HBM (32GB per chip)Cube Unit 一个 cycle 算 16×16×16 的 FP16 矩阵乘加——16384 次乘加操作。两个 Vector Unit 各算 256 次 FP16 逐元素操作。这些数字不是随意定的——Cube 的输出刚好是 16×16256 个元素Vector Unit 刚好能在下一个 cycle 处理这 256 个元素的 Activation。Tensor计算 为什么需要 Tile不是可选项是硬件约束Cube Unit 一次吃 16×16 的矩阵块。如果你给它一个 4096×4096 的矩阵——它没法一口吞下。Tensor计算 必须分块。这个分块叫 Tiling。Tile 大小由 L1 Buffer 容量决定。Ascend 910 的 L1 是 192KB。一个 GEMM 的 Tile 需要在 L1 上同时放下A 矩阵的一块M_TILE × K_TILE、B 矩阵的一块K_TILE × N_TILE、C 矩阵的一块M_TILE × N_TILE。三个块全是 FP16字节数加起来必须 ≤ 192KB - 几条 KB 的系统开销。Tile 占用 L1 的计算 M_TILE × K_TILE × 2B (A block) K_TILE × N_TILE × 2B (B block) M_TILE × N_TILE × 2B (C block) ≤ 192KB 典型配置Cube Unit 对齐 16 M_TILE128, N_TILE256, K_TILE32 A: 128×32×2 8KB B: 32×256×2 16KB C: 128×256×2 64KB 总计: 88KB —— L1 还绰绰有余可以放双缓冲的下一批数据AICore 执行链路一次 GEMM 的完整流程以一次 M4096、N4096、K4096 的 GEMM 为例Tile 配置 M_TILE128、N_TILE256、K_TILE32AICore 执行一次完整 GEMM 1. Scalar Unit 初始化 计算 M 方向 32 个 Tile、N 方向 16 个 Tile、K 方向 128 个 Tile 2. 外层循环M 方向32 次 for m_tile in range(32): 中层循环N 方向16 次 for n_tile in range(16): 3. DDR → L1DMA 搬运 A[m_tile, 0:32] 和 B[0:32, n_tile] 内层循环K 方向128 次 for k_tile in range(128): 4. Cube Unit: C_tile A_tile[k] B_tile[k] 同时Vector Unit 处理上一个 k_tile 的 Activation 同时Scalar Unit 准备下一个 k_tile 的地址 5. Vector Unit: 对 C_tile 做 Activation如 ReLU/GELU 6. L1 → DDRDMA 写回 C[m_tile, n_tile] 总 Cube 运算次数: 32×16×128 65536 次 16×16×16 GEMM Cube Unit 的 65536 次运算中Cube 和 Vector 并行重叠约 85%Tensor流转从 DDR 到 L1 再到 Cube一次 GEMM 计算中 Tensor 的流转路径DDR (HBM) → L1 Buffer → L0A/L0B → Cube Unit → L0C → L1 Buffer → DDR 每一步的延迟 DDR → L1: DMA 搬运延迟约 5-15μs 启动 带宽 200GB/s L1 → L0A/L0B: 1 cycle Cube Unit 计算: M_TILE × N_TILE × K_TILE / (16×16×16) cycles L0C → L1: 1 cycle L1 → DDR: DMA 写回 关键DDR ↔ L1 的 DMA 是异步的——Cube 算着当前 TileDMA 搬着下一批数据。 两者走独立的硬件通道互不阻塞。参考仓库Ascend C 算子编程语言catlass 算子模板库ops-blas 高性能 GEMMCANN 学习中心