跳到主要内容
昇腾AI芯片与算子开发

1.3 昇腾存储层次与数据流

从 HBM、L2 Cache 到 AI Core 内部的 Unified Buffer 与 L0 缓冲,梳理昇腾存储层次与数据搬运路径,并与 CUDA 内存模型做映射,为算子性能优化打基础

昇腾 存储层次 HBM Unified Buffer L0

上一章我们知道了 AI Core 有 Cube/Vector/Scalar 三个计算单元。但算力再强,数据喂不上去也没用。这一章我们聚焦昇腾的存储层次(Memory Hierarchy)——它决定了算子和训练能跑多快,也是理解 Ascend C 中「数据搬运」概念的前提。

📑 目录


1. 昇腾存储层次总览

昇腾的存储体系可以用一句话概括:

「片外 HBM 装大块数据,片上 L2 做中转缓存,AI Core 内部 Buffer 是计算的直接工作台。」

        HBM(片外,容量大、带宽高)
          │  数据搬运(DataCopy)
          ▼
        L2 Cache(片上共享)
          │
          ▼
   ┌───────────────────────────┐
   │   AI Core 内部             │
   │   ├─ Unified Buffer (UB)  │  ← 向量/通用计算的工作台
   │   ├─ L0A / L0B(Cube输入) │
   │   ├─ L0C(Cube输出)       │
   │   └─ 寄存器组(Register)  │
   └───────────────────────────┘

每一层都比上一层更快、但更小、更贵。优化昇腾算子的核心,就是让数据尽量停留在片上、减少 HBM 访问次数——这和 CUDA 里「减少全局内存访问、多用共享内存」是同一个道理。

2. HBM:片外大容量高带宽内存

HBM(High Bandwidth Memory,高带宽内存) 是昇腾片外的主内存,训练大模型时权重、梯度、激活、优化器状态全都住在这里。

关键认知:

  • 容量:910 系列训练芯片的 HBM 容量远大于推理芯片(典型值随代际变化,请以官方规格为准)。
  • 带宽:HBM 通过 3D 堆叠 + 宽接口获得极高带宽,是 GDDR 的数倍。Transformer 训练/推理中大量数据搬运都依赖 HBM 带宽。
  • 对比:HBM 之于昇腾 ≈ 显存(VRAM)之于 GPU。你在 GPU 上理解过的「显存带宽瓶颈(memory-bound)」概念,在昇腾上同样成立。

在 Ascend C 里,HBM 被称为 Global Memory,算子代码中通过指针访问;开发者需要显式地把数据从 Global Memory 搬到片上(DataCopy),这正是昇腾「显式数据搬运」风格的体现。

3. L2 Cache:片上共享缓存

L2 Cache 是所有 AI Core 共享的片上二级缓存,位于 HBM 与 AI Core 之间:

  • 作用:缓存频繁访问的数据(如权重的分块),减少对 HBM 的重复访问。
  • 共享性:多个 AI Core 共享 L2,因此 L2 也承担了「核间数据暂存与通信」的一部分角色。
  • 容量:远小于 HBM,但远大于 AI Core 内部 Buffer(数量级差异,以具体芯片为准)。

可以把它类比为 GPU 的 L2 Cache:GPU 里也有一块所有 SM 共享的 L2,用来缓存全局内存访问。

4. AI Core 内部存储:UB / L0A / L0B / L0C

这是昇腾最独特的地方——AI Core 内部有专为计算单元设计的几块 Buffer:

存储全称/职责主要使用方类比
UBUnified Buffer,统一缓冲区,AI Core 的「通用工作台」向量计算、数据中转近似 GPU 的共享内存(SMEM)
L0ACube 的输入 A 缓冲AI Cube 矩阵乘左矩阵近似 Tensor Core 的寄存器输入
L0BCube 的输入 B 缓冲AI Cube 矩阵乘右矩阵同上
L0CCube 的输出/累积缓冲AI Cube 结果累积近似 Tensor Core 的累积寄存器
寄存器通用寄存器组Scalar / 向量指令通用寄存器

关键点:

  1. UB 是 Ascend C 编程的「主场」:向量类算子(Add、Softmax 等)的数据通常先在 UB 里就位,然后让 AI Vector 计算。
  2. L0A/L0B/L0C 是 Cube 的专用通路:矩阵乘数据从 HBM/L2 直接灌入 L0A/L0B,算完累积在 L0C,这条路径几乎不经过通用寄存器。
  3. 容量都有限:UB/L0 每块容量都只有几十 KB 到几百 KB 级别,因此「数据太大放不下」时必须 Tiling(分块)——把大张量切成能塞进 Buffer 的小块循环处理。

5. 数据流:一条数据从 HBM 到计算单元的旅程

以一次向量 Add 算子为例,看数据的完整旅程:

1. 数据 a、b 在 HBM(Global Memory)中
2. Ascend C 代码中执行 DataCopy:
   HBM ──DataCopy──▶ UB(a、b 被搬进 Unified Buffer)
3. AI Vector 执行 Add: UB 中逐元素相加 → 结果写入 UB
4. 结果在 UB 中就位后,执行 DataCopy:
   UB ──DataCopy──▶ HBM(结果写回 Global Memory)

如果是矩阵乘(GEMM),旅程略有不同:

1. HBM ──DataCopy──▶ L0A / L0B(Cube 输入)
2. AI Cube:L0A × L0B ──▶ L0C(FP32 累积)
3. 若后续需要激活:L0C ──▶ 向量路径 ──▶ AI Vector 处理
4. 结果 ──▶ UB ──DataCopy──▶ HBM

可以看到:昇腾算子性能的关键 = 搬运次数与计算时间的匹配。如果数据搬运速度跟不上计算单元的速度,算力再强也会「饿着」(memory-bound)。

6. 与 CUDA 内存模型的映射

如果你有 CUDA 基础,下面这张映射表能帮你快速迁移直觉:

CUDA / GPU昇腾说明
Global Memory(全局内存)Global Memory(HBM)显式搬运、带宽宝贵
L2 CacheL2 Cache核间共享缓存
Shared Memory(共享内存)Unified Buffer(UB)都是片上可编程的「手工管理」Buffer
寄存器L0A/L0B/L0C + 寄存器组Cube 专用输入输出缓冲对应 Tensor Core 的寄存器路径
__syncthreads()数据同步/队列同步(EnQue/DeQue)昇腾用队列/同步原语管理 Buffer 生命周期

一个显著差异要特别提醒:CUDA 里数据从全局内存到共享内存的搬运是「隐式+手工并存」的,而昇腾 Ascend C 中 GM→UB 的 DataCopy 几乎是必经之路。所以昇腾算子代码里「搬运」部分占比很高,这既是负担(要写更多代码),也是机会(更可控、更利于极致优化)。

7. 存储层次对性能优化的启示

理解存储层次后,昇腾算子优化立刻就有了方向:

  1. 减少 HBM 访问:能留在片上(UB/L2)的数据尽量复用,避免反复搬运。
  2. 提升搬运效率:DataCopy 尽量连续、对齐,一次搬大块数据,避免零散访问。
  3. 算搬重叠(流水线):让数据搬运与计算并行(双缓冲/多缓冲),隐藏搬运延迟。
  4. 合理 Tiling:Tiling 大小要让数据恰好填满 UB/L0,既不多(放不下)也不少(浪费带宽)。

这些原则和 CUDA 优化中的「访存合并、共享内存复用、双缓冲」完全同构——性能优化的底层逻辑,跨硬件是相通的。

总结

  • 昇腾存储层次:HBM(Global Memory)→ L2 → AI Core 内部(UB / L0A / L0B / L0C)。
  • AI Core 内部存储分工明确:UB 是向量计算的主场,L0A/L0B/L0C 是矩阵计算(Cube)的专用通路。
  • 数据流 = 显式 DataCopy(GM↔UB)+ 计算单元执行 + 写回,搬运效率直接决定算子性能。
  • 与 CUDA 内存模型高度同构,GPU 经验可以迁移;昇腾的特殊性在于「显式搬运」的权重更高。
  • 优化的核心始终是:减少 HBM 访问、提高搬运效率、算搬重叠、合理 Tiling。

延伸阅读