---
tags: [昇腾, 异构计算, CANN]
doc_type: knowledge-note
aliases: [异构系统编程模型]
abstract: "整理异构计算基础概念、SPMD与SIMD/SIMT编程模型、昇腾处理器及CANN软件架构。"
finished: false
creation: 2026-10-15
返回目录: "[[计算机系/昇腾与CANN/大模型与算子专题学习导航|大模型与算子专题学习导航]]"
上一篇: "[[计算机系/昇腾与CANN/人工智能发展与大模型计算本质|人工智能发展与大模型计算本质]]"
下一篇: "[[计算机系/昇腾与CANN/CANN软件栈与Torch NPU实践|CANN软件栈与Torch NPU实践]]"
后续学习: ["[[计算机系/昇腾与CANN/Ascend C算子基础整理|Ascend C算子基础整理]]"]
---

# 异构计算基础与 CANN 架构整理

本篇讲解异构计算的概念、编程模型与 CANN 架构。具体接口、分片索引和代码实现见 [Ascend C 算子基础整理](Ascend%20C算子基础整理.md)。

## 1. 异构计算基础概念

### 1.1 什么是异构计算

**异构计算（Heterogeneous Computing）是让不同类型的处理器在同一系统中分工协作，利用各自的硬件特长完成任务。** 其思想可以概括为“让专业的芯片干专业的事”。

 多个同类型 CPU 核一起计算，也属于并行计算；异构计算进一步利用不同类型处理器的特长。因此，“并行”与“异构”描述的侧重点不同。
异构计算是将 CPU、GPU、NPU 等不同类型处理器整合在同一系统中，根据硬件特长分工协作的先进架构。通过发挥各处理器的核心优势，实现远超单一处理器的整体性能与能效比。
典型应用包括人工智能、自动驾驶、超级计算和多媒体处理。

### 1.2 为什么需要异构计算

异构计算主要回应以下四方面需求。

| 原因     | 核心问题                | 理解要点                     |
| ------ | ------------------- | ------------------------ |
| 架构瓶颈   | 单一 CPU 架构受存储墙与功耗墙约束 | 仅靠提高 CPU 性能，难以持续满足全部计算需求 |
| 算力需求增长 | AI 大模型等应用推动计算需求增长   | 需要更适合这类负载的计算能力           |
| 任务多样性  | 不同任务的计算特性差异很大       | 一种处理器难以对所有任务都同样高效        |
| 能效要求   | 数据中心与端侧都关注单位功耗的产出   | 特定任务可以利用专用加速器提高能效        |

“存储墙”可理解为数据供给跟不上计算需求，处理器可能花时间等待数据；“功耗墙”可理解为功耗与散热限制了性能继续提升的空间。

异构计算的目标是提高整体性能与能效。实际收益还取决于任务是否适合加速器，以及数据搬运和调度成本，并非所有任务都必然加速。

### 1.3 AI 应用、神经网络与算子的关系

AI 场景可以从三个层次理解：

| 层次 | 关注的问题 | 内容 |
| --- | --- | --- |
| AI 应用 | 最终完成什么任务 | 面向具体场景提供智能功能 |
| 神经网络模型 | 如何表达并学习计算规律 | 通过加权连接与非线性激活组织计算 |
| 算子 | 每一步具体计算如何执行 | 对张量执行矩阵乘法、卷积、激活、池化等运算 |

AI 应用逐渐从专用模型向通用大模型与场景适配发展。这里的应用、模型、算子是一条理解 AI 工程的路径，并不意味着所有 AI 方法都必须使用神经网络。
(算子就是编程加速的一种异构的体现)
在深度学习中，**算子是计算图中的基本计算执行单元**，以张量为输入输出，完成特定数学运算。

典型算子包括：

- `Conv2D`：二维卷积。
- `MatMul`：矩阵乘法。
- `ReLU`：激活函数。
- `MaxPool`：最大池化。

张量可以先理解为多维数组。计算图用节点表示计算，用连接关系表示数据依赖。理解模型整体结构之后，算子开发进一步关注每个计算任务在硬件上如何实现。

## 2. 异构系统编程模型

### 2.1 Host 与 Device 的组成

典型异构系统由 Host 与 Device 两部分组成。

| 对象 | 典型硬件 | 主要作用 |
| --- | --- | --- |
| Host，主机侧 | CPU | 准备资源、下发计算任务、等待并接收结果 |
| Device，设备侧 | GPU、NPU 等 AI 处理器 | 执行下发的计算任务 |
| Host Memory | 主机内存 | 保存主机侧使用的数据 |
| Device Memory | 设备内存 | 保存设备计算所需的输入与输出 |

Host 与 Device 表示系统中的角色。这里使用 CPU 作为 Host、昇腾 NPU 作为 Device。

### 2.2 一次计算如何协作完成

![[CANN2.png]]


一次计算包含五个基本步骤：

1. **准备与分配内存**：Host 侧准备输入；Device 侧申请计算所需的输入、输出空间。输入也可能已由上一个设备任务产生，此时不必重新从 CPU 搬入。
2. **数据搬入**：将输入从 Host Memory 拷贝到 Device Memory。
3. **启动计算**：由 Host 把算子任务下发到 Device。
4. **同步等待**：等待设备计算任务执行完成。
5. **数据搬出**：把结果从 Device Memory 拷贝回 Host Memory。

```text
Host：准备输入并安排设备内存
  │
  ├─ 将输入复制到 Device Memory
  ├─ 启动 Device 上的计算任务
  │                  │
  │              Device 执行计算
  │                  │
  ├─ 等待任务完成 ─────┘
  └─ 将结果复制回 Host Memory
```

**任务提交与任务完成需要区分。** 示例中的核函数调用是异步的，Host 提交之后，需要在使用结果或释放相关资源前正确等待。

这张流程描述的是主机与设备之间的协作。设备内部还可能发生 Device Memory 与片上存储之间的数据搬运，后续 Add 示例会单独展开。

### 2.3 SPMD：相同程序，不同数据分片
![[CANN1.png]]
SPMD 全称为 **Single Program Multiple Data**，含义是多个独立计算单元执行同一份程序，各自处理不同的数据分片。
每个核通常根据自己的编号处理不同分片；需要协作时也可以共享数据并同步。SPMD 不只用于异构系统，也可用于同类处理器组成的并行系统。
理解重点在于：程序可以相同，但输入地址或索引不同，因此各计算单元负责的数据不同。

如果将一组数据均匀分成若干段，每个计算单元都执行“读取自己的一段、计算、写回”，就体现了 SPMD 的思想。实际开发还需要确定分片大小、起始位置和边界。

### 2.4 SIMD：单指令多数据

SIMD 全称为 **Single Instruction Multiple Data**。一条指令对多个数据元素执行同类操作。

SIMD 的基本开发流程为：

1. **Tiling 分块**：划分数据，每个 Core 或 Block 负责其中一块，尽量均衡工作量。
2. **数据搬入**：通常显式调用搬运 API，将 Device Memory 中的数据搬到本地存储。
3. **数据计算**：调用 SIMD 指令对应的 API，完成对这一批数据的计算。
4. **数据搬出**：通常显式调用搬运 API，将本地结果写回 Device Memory。

由于数据搬运与计算是异步操作，需要同步保证依赖关系。例如，计算必须在输入搬运完成后使用数据，输出搬运必须在结果计算完成后读取结果。

 Add 算子正是这种模式：先搬入两个输入分片，再调用向量加法，最后写回结果。

### 2.5 SIMT：单指令多线程

SIMT 全称为 **Single Instruction Multiple Threads**，以多个线程执行程序的方式表达并行。

SIMT 的基本开发流程为：

1. **Tiling 分块**：建立线程索引与数据索引的对应关系。
2. **数据搬入**：通过指针访问 Device Memory，由硬件完成相应的数据加载。
3. **数据计算**：编写支持分支、循环的标量代码，多线程协作时安排同步。
4. **数据搬出**：通过指针将结果写回 Device Memory。

这里的“无需显式调用搬运 API”指上述设备端访问方式。实际数据仍然需要由硬件传输，也不能据此省略 Host 与 Device 之间必要的数据传输。

### 2.6 三种概念如何区分

| 概念 | 主要描述什么 | 编程时关注什么 |
| --- | --- | --- |
| SPMD | 多个计算单元如何执行同一份程序 | 每个单元负责哪一份数据 |
| SIMD | 一条指令如何处理多个数据元素 | 如何组织向量数据、搬运和计算 |
| SIMT | 多个线程如何执行程序 | 线程索引、数据索引和线程间协作 |

常见组合包括 **SPMD + SIMD** 和 **SPMD + SIMT**。SPMD 与 SIMD/SIMT 的关注层次不同，因此可以组合使用。

| 对比项   | SIMD 模式            | SIMT 模式      |
| ----- | ------------------ | ------------ |
| 数据划分  | 将一块数据交给 Core／Block | 建立线程到数据的索引映射 |
| 计算表达  | 调用处理一批元素的 SIMD API | 编写各线程执行的标量代码 |
| 设备端搬运 | 通常显式搬入本地存储、再写回     | 通常通过指针进行读写   |
| 同步    | 关注搬运与计算的依赖         | 关注线程协作的依赖    |

### 2.7 Tiling 到底要确定什么

Tiling 首先回答：**这份数据怎样分，哪个计算单元处理哪一部分？**

在 SIMD 示例中，要确定每个分片的大小以及起始位置。在 SIMT 的描述中，要确定线程索引如何对应数据索引。

均匀分片适合入门示例。实际分块还需要考虑尾部数据、复杂形状、核内循环和性能要求。

可以将三者记成：**SPMD 决定谁处理哪份数据，SIMD/SIMT 描述怎样表达并行，Tiling 决定每次处理多大一块。** Tiling 不是与 SPMD、SIMD、SIMT 并列的第四种执行模型。

例如 1000 个元素分给 4 个核，每核先负责 250 个元素；若片上每轮安排 128 个元素，就需要处理 128 和剩余 122 个元素。前一次切分是在核之间分工，后一次切分是在核内安排批次。尾块还要按接口选择掩码、补齐或其他合法处理方式，不能越界读取。SIMT 中也不要求线程与元素永远一一对应，一个线程可以通过循环处理多个元素。

`SetDevice(0)` 一类调用用于选择设备，不是搬运数据；Stream 是任务提交和排序的运行时对象，不是一块物理计算核心。等待某条流完成与等待整个设备完成的范围也不同。具体接口与两层搬运见[Ascend C 算子基础](Ascend%20C算子基础整理.md)。

对齐条件需要同时说明单位和接口，例如“地址按 32 字节对齐”不等于“数据类型为 32 位”。Cube 支持的类型、单次指令粒度与吞吐也随架构变化，不能从某个矩阵形状推导所有芯片都能在一个时钟周期完成；矩阵 Kernel 还包含搬运、标量控制和同步，融合场景也可能使用 AIV。具体见[矩阵算子与数据布局](Ascend%20C矩阵算子与数据布局.md)。

## 3. 昇腾 AI 处理器与 CANN 计算架构

### 3.1 昇腾处理器的代际概览

以下列出四个系列的典型配置，同系列不同型号可能有所差异。

| 系列 | 时间范围 | 架构版本号 | 典型计算单元配置 | 编程能力与特点 |
| --- | --- | --- | --- | --- |
| Atlas A1 | 2018—2022 | `1001` | 32 个核，AIC 与 AIV 耦合 | 支持 SIMD |
| Atlas A2 | 2023—2025 | `2201` | 24 个 AIC + 48 个 AIV | SIMD |
| Atlas A3 | 2025—2026 | `2201` | 24 个 AIC + 48 个 AIV | SIMD；更大算力与 384 卡超节点 |
| Atlas 950 | 2026—2027 | `3501` | 950PR：32 个 AIC + 64 个 AIV | 支持 SIMD 与 SIMT |

需要区分**产品系列与架构版本号**：A2、A3 是两个产品系列，但架构版本号均为 `2201`。

### 3.2 AIC、AIV 与存储配置

AIC 通常指 AI Cube，侧重矩阵计算；AIV 通常指 AI Vector，侧重向量计算。片上存储资源包括 UB、L1、L0A、L0B、L0C 等。

| 系列 | UB | L1 | L0A／L0B | L0C |
| --- | --- | --- | --- | --- |
| A1 | 256K | 1M | 各 64K | 256K |
| A2 | 192K | 512K | 各 64K | 256K |
| A3 | 192K | 512K | 各 64K | 256K |
| 950PR | 256K | 512K | 各 64K | 256K |

> [!warning] 规格待核实
> 本篇 L0C 表列 256K，而 SIMD 篇保留的原图列 128K；两处原始数值均保留。容量、峰值算力和产品时间范围须结合具体型号、统计口径与资料版本核实。参见 [[计算机系/昇腾与CANN/Ascend C SIMD硬件内存与同步|Ascend C SIMD硬件内存与同步]]。

950PR 的 Cube FP16 算力为 `432 TFLOPS`，Vector FP16 算力为 `54 TFLOPS`。

**设备全局内存与片上存储处于不同位置，片上容量会约束一次能处理的数据量。**

### 3.3 SIMD 与 SIMT 的硬件支持

**Atlas A2/A3** 采用 SIMD 编程模型。

Ascend 950 系列还支持 SIMT 和 Reg 矢量编程。

### 3.4 CANN 是什么

CANN 全称是 **Compute Architecture for Neural Networks**，是昇腾 AI 算力栈的核心基础软件平台。

它向上支持与适配 AI 框架，向下提供处理器的硬件抽象、编程支持与任务执行能力。应用开发者通过框架或库使用算力，算子开发者通过编程接口实现特定计算，运行时负责把任务下发到硬件。
![[CANN6.png]]
### 3.5 CANN 的三层职责

CANN 自下而上的主要职责可分为三层：

| 层次 | 核心职责 | 对应组件或例子 |
| --- | --- | --- |
| 运行时层 | 驱动使能与任务调度，将任务下发到硬件执行单元 | Runtime、驱动 |
| 编程与编译层 | 根据硬件提供编程抽象、开发接口与编译支持 | Ascend C、PyPTO、毕昇编译器 |
| 加速库层 | 提供计算与通信等通用实现 | 算子库、通信库、领域加速库 |

相关项目包括：

- 算子库：`ops-nn`、`ops-math` 等。
- 通信库：`hixl`、`shmem`、`hccl` 等。
- 领域加速库：`sip` 等。
- 图引擎相关项目：`ge`、`metadef`、`graph-autofusion` 等。

### 3.6 AI 框架适配与图引擎

AI 框架通过 **Framework Adapter（框架适配层）** 与下层能力衔接。

图引擎则处理计算图层面的优化。主要方式包括：

| 优化方式 | 理解补充 |
| --- | --- |
| 算子融合 | 在条件允许时将一些计算合并组织，减少中间环节的开销 |
| 内存复用 | 根据数据生命周期复用内存，减少不必要的内存占用 |
| 全局调度 | 从计算图整体安排任务，而不是只孤立考虑单个算子 |

单算子优化关注一个运算如何执行，图级优化关注多个运算如何衔接。两者共同影响整网训练与推理性能。

### 3.7 从应用到硬件的关系

下面按职责整理架构关系，帮助理解各组件的位置，不表示每个应用都必须依次调用所有组件：

```text
AI 应用与 AI 框架
        │
框架适配层（Framework Adapter）
        │
CANN 提供的能力
  ├─ 加速库：计算、通信、领域能力
  ├─ 图引擎：计算图优化
  ├─ 编程与编译：Ascend C、PyPTO、毕昇编译器
  └─ 运行时与驱动：任务下发、调度和硬件执行支持
        │
昇腾 AI 处理器
```

## 4. 复习与易混点

### 4.1 异构计算是否就是多个核一起计算？

多个核一起计算体现并行。异构计算还强调不同类型处理器根据硬件特长分工协作。

### 4.2 Host 启动计算后是否可以立即使用结果？

需要区分提交与完成。对于异步核函数调用，必须按正确的同步与数据传输顺序取得结果。

### 4.3 SPMD、SIMD、SIMT 是否是三选一？

不是。SPMD 描述多个单元执行同一程序、处理不同数据；SIMD/SIMT 描述并行计算的表达与执行方式。可以采用 SPMD + SIMD 和 SPMD + SIMT 两种组合。

### 4.4 SIMD 的数据搬入是否就是 CPU 到 NPU？

Host/Device 协作中的搬入是 Host Memory 到 Device Memory；SIMD 核函数中的搬入是 Device Memory 到设备本地存储。两者属于不同层次。

### 4.5 SIMT 是否完全不需要数据搬运或同步？

仍然存在数据传输，只是上述设备端访问方式由指针读写表达、硬件执行加载与存储。多线程协作仍需考虑同步，Host 与 Device 之间的传输也需要单独处理。

### 4.6 A2 与 A3 的架构版本号是什么？

均为 `2201`。不能把产品系列的编号直接当作架构版本号。

### 4.7 CANN 与 Ascend C 有什么区别？

CANN 是包含运行时、编程编译、加速库等能力的软件平台；Ascend C 是其中用于昇腾算子开发的编程语言与接口体系。

### 4.8 学完本篇应该能说明什么？

- 为什么需要 CPU 与加速器协作。
- 一次 Host/Device 计算的五个基本步骤。
- SPMD 与 SIMD/SIMT 的区别和组合关系。
- Tiling 如何把数据分配给计算单元。
- A2/A3 与 950 在编程能力边界。
- CANN 三层职责，以及框架适配和图引擎的作用。

掌握这些内容后，继续阅读 [Ascend C 算子基础整理](Ascend%20C算子基础整理.md)，把这些概念对应到具体代码。
