2019 字
10 分钟
并行计算与 CUDA 基础
2026-07-16
无标签

1. 并行计算概念#

并行计算是指在拥有多个计算资源(例如多个核心或多台计算机)时,将一个大问题拆分为多个小问题,并在不同计算资源上同时处理这些子问题。

并行计算主要分为两个方向:

  • 计算机架构:关注硬件层面如何支持并行性。
  • 并行程序设计:关注如何利用计算机架构的能力并发地解决问题。

现代芯片设计越来越倾向于将多个核心集成到一片芯片上,因此并行计算已经成为计算机体系结构与程序设计中的重点。

2. 并行性与数据并行#

所有并行程序一定是并发程序,但包含并发任务的程序不一定是并行程序。

并行方式通常可以分为两类:

  • 任务并行:当多个任务或函数可以独立并大规模地并行执行时,称为任务并行。重点在于对任务进行分配。
  • 数据并行:当可以同时处理大量数据时,称为数据并行。重点在于对数据进行分配。

CUDA 编程非常适合解决数据并行问题。对于大数据集处理类应用,数据并行模型可以有效提升计算单元的吞吐能力,并将数据映射到并行线程上。

2.1 数据并行程序设计#

数据并行程序设计的核心思想是:将数据按照线程进行划分,使每个线程处理其中一部分数据。

常见的数据划分方式包括:

  • 块划分:每个线程作用于一段连续数据,通常每段数据大小相同。
  • 周期划分:每个线程处理数据的多个部分,线程之间按周期分配数据块。

块划分中,一组连续数据被分配到一个块内,每个数据块通常由一个线程按任意次序处理,且线程在同一时间通常只处理一个数据块。

周期划分中,相邻线程处理相邻的数据块,每个线程可以处理多个数据块。为一个线程分配新的数据块时,意味着要跳过与现有线程相同数量的数据块。

3. 计算机架构#

3.1 常见并行架构#

  • SIMD:单指令流处理多个数据流。典型例子是向量机。
  • MISD:较少见,多个指令流处理同一个数据流。
  • MIMD:多个核心使用多个指令流异步处理多个数据流,实现空间上的并行性。

许多 MIMD 架构还包含 SIMD 执行的子组件。

3.2 架构层次与扩展方向#

并行系统的演进通常体现在以下几个方面:

  • 降低延迟(微秒级)。
  • 提高带宽(MB/s、GB/s)。
  • 提高吞吐量(GFLOPS,表示每秒十亿次浮点运算)。

按内存组织方式,还可以进一步划分为:

  • 分布式内存的多节点系统。
  • 共享内存的多处理器系统。

在多节点系统中,大型计算引擎由多个通过网络连接的处理器组成。每个处理器拥有自己的本地内存,处理器之间通过网络通信。

在多处理器架构中,系统规模通常从双处理器到几十个甚至几百个处理器不等。这些处理器要么关联同一物理内存,要么共享低延迟链路(如 PCI-Express 或 PCIe)。共享内存意味着共享地址空间,但并不一定意味着单独的物理内存。此类系统既包括多核单芯片系统,也包括由多个芯片组成的计算机系统。如今,多核架构已经基本取代单核架构。

4. GPU 架构#

GPU 代表一种众核架构,通常结合以下特征:

  • 多线程
  • MIMD(多指令多数据)
  • SIMD(单指令多数据)
  • 指令级并行

NVIDIA 将这种架构称为 SIMT(单指令多线程)。

尽管可以用“多核”和“众核”来区分 CPU 和 GPU 的架构,但二者本质上是完全不同的:

  • CPU 核心较重,适合处理复杂控制逻辑,优化串行程序执行。
  • GPU 核心较轻,适合处理控制逻辑较简单的数据并行任务,更强调并行程序的吞吐量。

5. 异构计算#

异构计算可以简单理解为:CPU 负责控制,GPU 负责执行重计算任务。

典型的异构计算节点通常包括:

  • 两个多核 CPU 插槽
  • 两个或更多众核 GPU

GPU 本质上可以看作 CPU 的协处理器,也是最常见的硬件加速器之一。

在 CUDA 语境中:

  • Host:CPU 所在的位置。
  • Device:GPU 所在的位置。

主机代码运行在 CPU 上,负责应用初始化以及管理设备端的环境、代码和数据。 设备代码运行在 GPU 上,用于提升并行计算的执行速度。

NVIDIA 的 GPU 计算平台包括:Tegra、GeForce、Quadro、Tesla。

NVIDIA 从 2010 年的 Fermi(首款完整 GPU 计算架构)到 2012 年的 Kepler,再到嵌入式 Tegra K1,不断推动 GPU 在高性能计算领域的应用和算力提升,覆盖地震、生化、气候、金融等场景。

5.1 GPU 特征与性能指标#

GPU 的常见特征指标:

  • CUDA 核心数量
  • 内存大小

GPU 的核心性能指标:

  • 峰值计算性能
  • 内存带宽

其中,峰值计算性能(GFLOPS/TFLOPS)和内存带宽(GB/s)是衡量 GPU 计算能力的两个核心指标。Fermi 到 Kepler 架构在这两方面均有显著提升。

5.2 计算能力#

NVIDIA 使用计算能力主版本号标识 GPU 架构世代:

  • 1 = Tesla
  • 2 = Fermi
  • 3 = Kepler

相同主版本号通常表示相同的核心架构。

5.3 GPU 与 CPU 的差异#

  • CPU 适合处理数据规模较小、并行性较低的任务。
  • GPU 更适合处理计算密集型、并行性高的任务。

因此,程序通常会将计算密集型部分交给 GPU,而将串行部分保留在 CPU 上执行。

CPU 的线程通常是重量级的,上下文切换成本较高,因此可支持的线程数量远少于 GPU。四核 CPU 通常可同时运行 16 个线程,如果支持超线程则可进一步翻倍;而 GPU 在每个多处理器上最多可支持 1536 个线程,16 个多处理器的 GPU 最多可支持约 24000 个线程。

6. CUDA 历史#

时间版本 / 架构主要特性
2006G80 / CUDA 首发GTX 8800,首个支持通用计算的 GPU
2008CUDA 2.0支持双精度
2010CUDA 3.0 / Fermi支持 C++
2012CUDA 5.0 / KeplerDynamic Parallelism
2017CUDA 9.0 / Volta引入 Tensor Core
2020CUDA 11.0 / AmpereMIG 多实例
2024CUDA 12.x / Hopper / Blackwell支持 FP8 / FP4

FP8 和 FP4 是极低精度浮点格式,用于加速 AI 推理和训练,并节省显存与带宽。

7. CUDA 驱动 API 与运行时 API#

CUDA 驱动 API 和运行时 API 在性能上没有明显差异,但二者互斥。

CUDA 编程真正影响性能的因素,是线程组织方式和内存使用方式,而不是 API 选择本身。

nvcc 会将 CUDA 代码拆分为两部分:

  • 主机代码:标准 C,由主机 C 编译器编译。
  • 设备代码:核函数,由 CUDA C 扩展标记,并由 nvcc 编译。

在链接阶段,会加入 CUDA 运行时库,以处理内核调用和 GPU 操作。

8. CUDA 编程结构#

一个典型的 CUDA 编程结构包括以下 5 个步骤:

  1. 分配 GPU 内存。
  2. 将数据从 CPU 内存拷贝到 GPU 内存。
  3. 调用 CUDA 内核函数完成指定运算。
  4. 将结果从 GPU 拷回 CPU 内存。
  5. 释放 GPU 内存空间。

9. 编写 CUDA 的要求#

编写 CUDA 程序时,建议具备以下基础:

  • 熟悉 GPU 结构。
  • 了解 CPU 架构,例如数据局部性(时间局部性、空间局部性)等原理。
并行计算与 CUDA 基础
https://www.dongyanzhang.com/posts/cuda-c/cuda-c-001/
作者
阿东阿言
发布于
2026-07-16
许可协议
CC BY-NC-SA 4.0