CUDA: New Features and Beyond

Stephen Jones, GTC 2023

目录

引言:摩尔定律的终结

报告开篇引用了NVIDIA CEO Jensen Huang的论断:“摩尔定律已死(Moore's Law is dead)”。

这一论断进一步阐释为:计算不再仅仅是芯片问题,而是一个软件和芯片协同的问题。这为后续探讨超越传统芯片缩放的计算新范式奠定了基础。

摩尔定律的三大阶段

第一阶段:登纳德缩放定律 (Dennard Scaling)

摩尔定律的第一个发展阶段由登纳德缩放定律主导,该阶段持续至约2007年。其核心思想是通过不断缩小晶体管的线宽(line size)来实现性能的翻倍。

Page 4, 登纳德缩放定律示意图
Page 4, 登纳德缩放定律示意图

登纳德缩放的终结

大约在2005-2010年间,登纳德缩放达到了物理极限。随着线宽缩小,功耗密度增加导致散热问题难以解决,使得单纯提高处理器频率的路径不再可行。如下图所示,处理器频率在2005年后趋于平缓,增长停滞。

为了继续提升性能,行业转向了增加处理器核心数量的策略。下图右侧展示了从2005年左右开始,处理器核心数量呈指数级增长的趋势。

Page 6, 处理器频率与核心数趋势图
资料来源:Karl Rupp, "40 years of microprocessor trend data", https://github.com/karlrupp/microprocessor-trend-data

第二阶段:单晶片缩放 (Single-Die Scaling)

随着登纳德缩放的结束,摩尔定律进入了第二阶段,即单晶片缩放。这一阶段从约2007年持续至今,其主要特征是通过在单个芯片上集成越来越多的核心来提升计算能力。

Page 7, 摩尔定律的两个阶段对比
Page 7, 摩尔定律的两个阶段对比

单晶片缩放的终结:光罩极限 (Reticle Limit)

单晶片缩放同样面临物理极限。在半导体制造的光刻工艺中,通过光罩(reticle mask)将电路图案投影到晶圆上。光罩的尺寸存在上限,这限制了单个芯片所能达到的最大面积,即“光罩极限”。这使得通过无限增大单晶片面积来增加核心数量的方法变得不可行。

Page 8, 光刻工艺与单晶片缩放示意图
Page 8, 光刻工艺与单晶片缩放示意图

第三阶段:多晶片缩放 (Multi-Die Scaling)

随着单晶片缩放逼近极限,摩尔定律进入了第三个阶段:多晶片缩放。该阶段始于当前并延伸至未来,其核心思想是通过组合多个独立的晶片(die)来继续提升计算能力,从而绕过单晶片的尺寸限制。

Page 14, 摩尔定律的三个阶段
Page 14, 摩尔定律的三个阶段

多晶片缩放可以通过2D(将多个晶片并排封装在同一基板上)或3D(将多个晶片垂直堆叠)的方式实现,从而构建出远超单个光罩极限的强大处理器。

Page 15, 多晶片缩放的2D与3D实现方式
Page 15, 多晶片缩放的2D与3D实现方式

异构计算:应对缩放极限

解决方案:异构硬件 (Heterogeneous Hardware)

为了克服光罩极限,硬件设计转向了专业化和异构化。异构(heterogeneous)指由性质截然不同的部分组成。在硬件领域,这意味着集成多种专用的处理单元,每种单元负责处理特定类型的计算任务,以提高整体效率。

例如,现代GPU中集成了浮点运算单元、纹理映射单元、光栅化单元和向量单元等多种专用硬件。

Page 9, 异构硬件组件示例
Page 9, 异构硬件组件示例

以NVIDIA Ada微架构为例,它在一个图形处理集群(graphics processing cluster)中集成了多个纹理处理集群(TPC),每个TPC又包含流式多处理器(SM)。每个SM内部则包含了用于不同任务的专用核心,如用于图形的第三代RT Core、用于AI计算的第四代Tensor Core,以及传统的FP32/INT32计算单元等。这种设计体现了高度的硬件异构化。

Page 10, NVIDIA Ada微架构中的异构硬件
Page 10, NVIDIA Ada微架构中的异构硬件

解决方案:异构软件 (Heterogeneous Software)

软件同样由不同语言编写的异构组件构成。应用程序通常会结合使用多种组件和库。

以Python中的科学计算为例,用户应用程序为了生产力通常使用Python编写,但其调用的NumPy库为了追求极致性能,其底层是由C和C++实现的。

Page 11, Python中的异构编程示例
Page 11, Python中的异构编程示例

整合:异构计算 (Heterogeneous Computing)

异构计算是结合不同类型的处理器(如CPU和GPU)协同工作,每种处理器专注于其擅长的执行类型。单个应用程序可以同时利用多个处理器,将计算密集型任务卸载到GPU,而控制和串行任务则由CPU处理。

Page 12, 异构计算概念图
Page 12, 异构计算概念图

例如,在一段C++代码中,可以通过调用GPU加速的cuBLAS库(如cublasSaxpy函数)来执行大规模并行计算,从而实现CPU和GPU的协同工作。

Page 13, 调用GPU库的异构计算代码示例
Page 13, 调用GPU库的异构计算代码示例

Grace/Hopper 超级芯片

多Die异构设备

多Die(Multi-Die)异构设备是多晶片缩放阶段的核心概念。如下图所示,一个单一的多Die设备内部可以集成多种不同的处理单元(Die),并连接到不同类型的外部存储器,例如DDR内存和HBM(高带宽内存)。这种设计允许将不同功能的芯片集成在一个封装内,以实现更高的性能和效率。

Page 16 - 多Die异构设备示意图
Page 16 - 多Die异构设备示意图

Grace/Hopper超级芯片是多Die异构设备的一个具体实现。

Page 17 - Grace/Hopper 超级芯片实物图
Page 17 - Grace/Hopper 超级芯片实物图

架构与带宽

Grace/Hopper超级芯片通过NVLink C2C(Chip-to-Chip)技术将NVIDIA Grace CPU和Hopper GPU紧密地连接在一起。这种集成架构旨在解决计算问题,正如幻灯片中引述的观点:“...计算不仅仅是芯片问题,它是一个软件和芯片问题。”

其关键架构和带宽规格如下:
- Grace CPU:连接到240 GB的CPU LPDDR5X内存,带宽为 500 GB/s
- Hopper GPU:连接到96 GB的GPU HBM3内存,带宽高达 4000 GB/s
- NVLink C2C:连接CPU和GPU的内部总线,提供 900 GB/s 的双向带宽。
- 高速I/O:CPU侧提供4个16x PCIe-5接口,总带宽为 512 GB/s
- NVLink网络:GPU侧提供18个NVLINK 4接口,用于连接多达256个设备,总带宽为 900 GB/s

Page 20 - Grace/Hopper 超级芯片架构及带宽详情
Page 20 - Grace/Hopper 超级芯片架构及带宽详情

系统扩展性

通过NVLink网络,最多可以将256个Grace/Hopper超级芯片互连,构建大规模的计算集群。每个超级芯片还配备了100 GB/sec的Infiniband NDR400网络接口,用于与其他节点通信。

Page 21 - NVLink 连接多达256个超级芯片
Page 21 - NVLink 连接多达256个超级芯片

这种架构支持构建由多个Hopper GPU组成的高性能多芯片系统,如下图所示。

Page 30 - 多芯片系统示意图
Page 30 - 多芯片系统示意图

幻灯片同时展示了计算扩展的三个层次:
- Multi-die:在单个芯片封装内集成多个计算裸片。
- Multi-chip:在单个主板或模块上集成多个芯片。
- Multi-node:通过网络连接多个独立的计算节点(服务器)。

计算扩展的三个层次
计算扩展的三个层次

全局数据访问与统一内存

Grace/Hopper架构的一个核心特性是实现了CPU和GPU之间无缝的数据访问。

全局缓存一致性访问

通过NVLink C2C,CPU和GPU可以实现对彼此物理内存的缓存一致性访问(Cache-coherent access)。
- Grace CPU读取Hopper内存:CPU可以将GPU内存中的数据取回至其L3缓存。当GPU内存中的数据发生变化时,CPU L3缓存中对应的缓存行会被置为无效(evict)。
- Hopper GPU读取Grace内存:GPU可以通过CPU L3缓存加载CPU内存中的数据。CPU和GPU都可以命中缓存中的数据。当CPU内存中的数据发生变化时,GPU缓存中对应的缓存行会得到更新(update)。

Page 22 - CPU与GPU的全局数据访问机制
Page 22 - CPU与GPU的全局数据访问机制

Grace/Hopper统一内存

地址转换服务(Address Translation Service, ATS)是实现统一内存的关键。ATS为整个系统创建了一个单一的共享页表,使得CPU和GPU可以完全访问彼此的内存分配。通过NVLink C2C,处理器可以访问系统内的任何物理内存,而无需进行数据迁移。

Page 23 - 基于ATS的Grace/Hopper统一内存架构
Page 23 - 基于ATS的Grace/Hopper统一内存架构

高带宽内存访问与自动数据迁移

  • GPU访问CPU内存:Hopper GPU能够以高达 500 GB/s 的速度(即CPU内存的满速)访问Grace CPU的内存。实测显示,对于GPU流式内核,访问CPU内存的带宽可达到 485 GB/s
Page 24 - GPU访问CPU内存的带宽
Page 24 - GPU访问CPU内存的带宽
  • GPU访问自身内存:Hopper GPU访问其本地HBM3内存的速度则快得多,带宽高达 4000 GB/s。实测带宽可达到 3732 GB/s
Page 25 - GPU访问自身HBM内存的带宽
Page 25 - GPU访问自身HBM内存的带宽
  • 自动数据迁移:为了优化访问速度,系统能够自动迁移受管内存(managed memory)和CPU分配的内存。例如,可以将频繁被GPU访问的数据从CPU内存迁移到GPU的HBM内存中。
Page 26 - 自动数据迁移示意图
Page 26 - 自动数据迁移示意图
  • 迁移后的无缝访问:数据迁移后,得益于ATS共享页表,CPU和GPU都能自动访问数据在GPU内存中的新位置,无需修改代码。
Page 27 - ATS支持迁移后数据的无缝访问
Page 27 - ATS支持迁移后数据的无缝访问

不同工作负载下的性能表现

在一系列算法和应用上,Grace/Hopper超级芯片的性能表现优于传统的x86 CPU搭配NVIDIA A100或H100 GPU的平台。如下图所示,在OpenFOAM、CP2K RPA、NAMD、CuCo以及Hash Join等多种工作负载下,Grace Hopper(绿色柱)均展现出显著的相对性能优势。

Page 28 - Grace/Hopper在不同工作负载下的性能对比
Page 28 - Grace/Hopper在不同工作负载下的性能对比

CUDA 平台详解:三大维度

计算的未来必然是多节点的。为了解决最大规模的问题,需要将成百上千个计算节点连接在一起,形成强大的计算集群。CUDA 平台通过其三个维度——语言、抽象层和规模——为这一挑战提供了全面的解决方案。

多节点服务器集群
多节点服务器集群

维度一:作为GPU计算平台 (语言)

CUDA 并不仅仅是 CUDA C++。它是一个支持多种编程语言和 API 的综合性平台,旨在为 GPU 加速计算提供支持。

  • 核心语言:最初以 CUDA C++ 为核心。
  • 扩展支持:逐渐扩展到支持 CUDA FORTRANOpenCL
  • 标准化语言集成:许多标准并行编程语言也支持 GPU 计算,例如 OpenACC, OpenMP, 以及 Standard C++
  • 更广泛的生态系统:许多非 NVIDIA 直接支持的语言也可以通过社区或第三方库利用 GPU 加速,包括 Python, Julia, MATLAB, Ada, Haskell, R 等。

这些不同的语言和接口最终都汇集到底层的编译栈。

CUDA 支持的多种语言
CUDA 支持的多种语言

所有这些高级语言和接口都构建在一个统一的编译平台之上,该平台包括:
- NVVM / LLVM IR:一个基于 LLVM 的编译器中间表示,用于优化代码。
- PTX Assembly ISA:并行线程执行(Parallel Thread Execution)指令集架构,是 NVIDIA GPU 的一种稳定的汇编语言。

CUDA 平台架构
CUDA 平台架构

维度二:抽象层平台

CUDA 不仅是一个语言平台,还是一个分层的抽象平台,开发者可以根据应用需求选择最合适的抽象层级。

CUDA 的抽象层
CUDA 的抽象层

这些抽象层级从底层到顶层包括:

  1. 编译栈 (Compilation Stack):提供最底层的控制,包括 NVVM/LLVM IR 和 PTX 汇编 ISA。
  2. 并行语言 (Parallel Languages):包括 OpenACC, OpenMP, Standard C++, CUDA FORTRAN, CUDA C++, OpenCL, Python, Julia, MATLAB 等。
  3. NVIDIA 加速库 (NVIDIA Accelerated Libraries):提供高度优化的特定领域函数库,如图形学、数学计算、深度学习等,例如 cuBLAS, cuDNN, TensorRT, cuSOLVER, cuFFT, Math API, NPP 等。
  4. 开发者与应用生态系统 (Developer & Application Ecosystem):提供最高级别的抽象,包括:
    • 框架 (Frameworks):如 PyTorch, TensorFlow, Jax, Modulus, Triton 等。
    • 软件开发工具包 (SDKs):面向特定行业应用的工具包,如医疗设备、能源、自动驾驶汽车等。
CUDA 抽象层详解
CUDA 抽象层详解

CUDA 生态系统提供了一个广泛的选择谱系。开发者可以自由组合与匹配不同层级的语言、库、框架和SDK,为自己的应用选择最佳的抽象层级。

CUDA 生态系统选择谱系
CUDA 生态系统选择谱系

维度三:规模 (Scale)

在多节点编程模型中,存在一个从追求更高生产力到追求更强控制力的权衡谱系。

生产力与控制力的权衡谱系
生产力与控制力的权衡谱系

不同的多节点编程模型位于这个谱系的不同位置:

  • 更高生产力 (Greater productivity):模型更自动化,对开发者透明,易于使用。
  • 更强控制力 (Greater control):模型提供更细粒度的控制,允许开发者进行深度优化,但复杂性也更高。

沿此谱系的编程模型包括:
cuNumeric -> Legate -> Legion -> Multi-GPU Libraries -> NCCL -> CUDA-Aware MPI -> NVSHMEM

多节点编程模型谱系
多节点编程模型谱系

开发者需要根据应用需求,在生产力与控制力之间找到最合适的平衡点。

  • 示例:cuNumeric (高生产力)

    • 描述:NumPy API 的隐式并行实现。
    • 特点:完全隐式的并行化,对应用程序透明。开发者只需使用熟悉的 NumPy 接口,底层即可自动实现多节点扩展。
  • 示例:NVSHMEM (强控制力)

    • 描述:OpenSHMEM 的 GPU 实现。
    • 特点:提供显式并行的编程模型,允许通过加载/存储操作访问分区的全局地址空间,为专家级用户提供了极致的性能控制。
cuNumeric 和 NVSHMEM 在谱系中的位置
cuNumeric 和 NVSHMEM 在谱系中的位置

多节点系统开发:从生产力到控制力

多节点编程模型可以看作一个谱系,一端是更高的生产力,另一端是更强的控制力。这个谱系可以分为三种并行模式:

  1. 隐式并行 (Implicit parallelism): 相同的代码必须能够在任何加速器类型和任何机器规模上实现性能可移植。例如:cuNumeric, Legate。
  2. 托管并行 (Managed parallelism): 应用程序或者提供源代码标记,或者调用可扩展的库,由运行时处理扩展。例如:Legion, 多GPU库。
  3. 显式并行 (Explicit parallelism): 应用程序通过手动或通信API直接管理数据交换和分发。例如:NCCL, CUDA-Aware MPI, NVSHMEM。
Page 48
Page 48

隐式并行 (Implicit Parallelism)

隐式并行的核心思想是,应用程序开发者使用顺序API,这些API可以映射到任何规模的系统上,从单个设备到大型集群,而无需修改应用程序代码。

Page 49
Page 49

Legate: 一个隐式并行框架

Legate是一个为隐式并行设计的框架。应用程序通过顺序API调用Legate运行时。Legate框架主要由以下几部分组成:

  • 生产力/可组合性层 (Productivity / Composability Layer): 加速库的开发。
  • 通用运行时系统 (Common Runtime System): 可扩展地提取隐式并行性。
  • 加速领域库 (Accelerated Domain Libraries): 最大化单个加速器的性能。

通过Legate,支持Legate的库(Legate-Enabled Libraries)可以被Legate运行时隐式地扩展。

Page 50
Page 50

Legate启用的库采用基于任务的模型,其特点是没有显式同步和数据移动,因此它们之间是可组合的 (composable)

Page 54
Page 54

Legate通过统一的数据抽象来实现库之间的可组合性。不同的任务通过映射同一个多维数组或“存储”(store)的分区来交换数据。Legate运行时会根据任务依赖关系自动复制或移动数据。

Page 55
Page 55

cuNumeric: NumPy API的隐式并行实现

cuNumeric是基于Legate框架构建的NumPy API的隐式并行实现。它允许现有的NumPy应用程序在无需修改代码的情况下扩展到数千个GPU。

Page 56
Page 56

cuNumeric的算子(operator)可以分解为任务逻辑(Tasking logic)和计算任务(Computation tasks)。

Page 57
Page 57

性能表现:
cuNumeric的Beta版本于2023年3月发布。性能测试显示,cuNumeric在GPU数量从1个扩展到1024个时,其标准化吞吐量呈现出近线性的增长。

相关讲座: cuNumeric and Legate: How to Create a Distributed GPU Accelerated Library [S51789]

Page 58
Page 58

通过加速库实现托管并行 (Managed Parallelism)

托管并行是多节点编程模型谱系中的中间地带。在这种模式下,应用程序通过调用可扩展的库或使用源代码标记来管理并行性,而具体的扩展工作则由运行时系统在后台处理。

Page 59
Page 59

多GPU多节点 (MGMN) 库

NVIDIA提供了丰富的加速库,支持多GPU多节点环境。这些库分为:
* 主机库 (Host Libraries): 如cuBLAS, cuFFT, cuSOLVER, cuTENSOR, NPP, CURAND等。
* 设备库 (Device Libraries): 如cuFFTDx, cuBLASDx, CUDA Math API, CUTLASS等。

这些库涵盖了线性代数、稀疏矩阵运算、张量运算、求解器、随机数生成、图像处理、量子计算等多个领域。

Page 60
Page 60

NVIDIA 加速库新特性与性能

cuSOLVERMp: 分布式对称特征值求解器

该部分展示了 cuSOLVERMp 在 Selene SuperPOD 上的弱扩展性表现,并与 ELPA1 进行了比较。

  • 测试配置:

    • 每个 GPU 上的本地矩阵大小为 32768²。
    • 使用双精度实数数据。
  • 性能:

    • 在 130K, 262K, 524K 规模的问题上,相较于 ELPA,实现了约 1.6 倍的加速。
    • 在 1M² 规模的问题上,实现了 1.35 倍的加速。
  • 弱扩展性测试结果:

    • 下图展示了在不同数量的 GPU 网格下(从 2x2 到 32x32),cuSOLVERMp 相较于 ELPA1 的运行时间。cuSOLVERMp 在所有测试规模上都表现出更低的运行时间。
    • 在 1024 个 GPU 上,cuSOLVERMp 的性能是 ELPA1 的 1.35 倍。
Page 61, cuSOLVERMp 与 ELPA1 在 Selene SuperPOD 上的弱扩展性 PDSYEVD 性能对比。
Page 61, cuSOLVERMp 与 ELPA1 在 Selene SuperPOD 上的弱扩展性 PDSYEVD 性能对比。

cuFFTMp + JAX

该部分展示了 cuFFTMp 与 JAX 框架集成后的强扩展性性能。

  • 强扩展性 (Strong-scaling): 随着 GPU 数量的增加,求解时间相应减少,理想情况下应呈现 1/N 的曲线。
  • 测试: 针对 2048-cube, fp32 的配置进行了测试。
  • 结果:
    • 图表显示,JAX+cuFFTMpcuFFTMp 的性能随着 GPU 数量从 8 个增加到 2048 个,求解时间显著下降,其扩展性表现紧密贴合了理想的缩放曲线。
    • JAX+cuFFT(未使用 Mp 版本)的性能扩展性较差,求解时间下降缓慢。这凸显了 cuFFTMp 在多 GPU 环境下的优势。
Page 62, cuFFTMp 在 2048-cube, fp32 配置下的强扩展性性能图,比较了 JAX+cuFFT、JAX+cuFFTMp 和 cuFFTMp 的表现。
Page 62, cuFFTMp 在 2048-cube, fp32 配置下的强扩展性性能图,比较了 JAX+cuFFT、JAX+cuFFTMp 和 cuFFTMp 的表现。

cuFFTMp 在 H100 GPU vs. A100 上的性能

此页对比了 cuFFTMp 在 H100 和 A100 GPU 上的性能表现。

  • 测试配置:

    • 问题规模: 1024-cube, fp32
    • GPU 数量: 2 至 16 个
  • 性能对比:

    • 左图显示,在不同 GPU 数量下,H100 的 TFLOPS 性能均显著高于 A100。
    • 右图量化了 H100 相对于 A100 的加速比,在 2、4、8、16 个 GPU 的配置下,加速比分别为 1.8x、1.7x、1.7x 和 2.3x。
Page 64, cuFFTMp 在 H100 与 A100 GPU 上的性能对比及 H100 的加速比。
Page 64, cuFFTMp 在 H100 与 A100 GPU 上的性能对比及 H100 的加速比。

历代 Tensor Core 性能

此图表展示了 H100-SXM GPU 相对于 V100 和 A100 在矩阵乘法(GEMM)方面的代际性能提升。

  • 基准: 所有性能均以 A100 性能为 1.0x 进行归一化。
  • 性能提升亮点:

    • INT8: H100 相对于 A100 实现了 4.6x 的性能提升。
    • FP16: H100 实现了 3.5x (FP16->FP16) 和 3.4x (FP16->FP32) 的性能提升。
    • BF16->FP32: H100 实现了 3.4x 的性能提升。
    • TF32: H100 实现了 3.6x 的性能提升。
    • FP64: H100 实现了 3.5x 的性能提升。
  • 结论: H100-SXM 在所有测试的数据类型上都展现了相对于前代产品(尤其是 A100)的显著性能飞跃。

Page 65, V100, A100, H100-SXM 三代 GPU 在不同精度下 GEMM 性能的相对加速比。
Page 65, V100, A100, H100-SXM 三代 GPU 在不同精度下 GEMM 性能的相对加速比。

cuBLASLt 中的 FP8 矩阵乘法

NVIDIA Hopper 架构引入了对 FP8(8位浮点)数据类型的支持,cuBLASLt 库提供了实现 FP8 矩阵乘法的流程。

  • FP8 矩阵乘法流程:

    1. 矩阵乘法 (Matrix multiply): 两个 FP8 输入操作数 op(A)op(B) 通过 FP8 TensorOp 进行计算,内部累加精度为 fp32。
    2. 反量化 (Dequantization): 将 fp32 结果与输入缩放因子 scaleAscaleB 相乘,并加上偏置项 C(已乘以其缩放因子 scaleC)。
    3. Epilogue: 对中间结果 D_temp 应用融合操作(如激活函数等)。
    4. 量化 (Quantization): 计算 D_tempamaxD 值,并乘以输出缩放因子 scaleD,最终将结果量化为 FP8 格式的输出 D
  • 灵活性: 该流程也可以直接输出 fp16、bf16 或 fp32 格式的结果。

Page 66, FP8 矩阵乘法与缩放的流程图。
Page 66, FP8 矩阵乘法与缩放的流程图。

这一流程强调了“计算不仅仅是芯片问题,而是软件和芯片共同的问题”,即需要硬件(FP8 Tensor Core)和软件(cuBLASLt 等库)的协同才能发挥最大效能。

cuBLAS FP8 在 NVIDIA H100 和 L4 GPU 上的应用性能

此页展示了使用 FP8 在大型语言模型训练和推理任务中带来的实际性能提升。

  • GPT-3 175B 训练(矩阵乘法):

    • H100-SXM 使用 BF16 相对于 A100 (BF16) 有 2.5x 的提升。
    • H100-SXM 混合使用 BF16 和 FP8,性能提升可达 3.9x。
  • BERT large 推理(预览):

    • L4 GPU 使用 FP16 相对于 T4 (FP16) 有 2.5x 的提升。
    • L4 GPU 使用 FP8,性能提升可达 4.2x。

注:推理性能是在一系列批处理大小和平均序列长度上测得的平均值。

Page 68, 使用 FP8 在 GPT-3 训练和 BERT 推理任务中相较于基线的性能加速比。
Page 68, 使用 FP8 在 GPT-3 训练和 BERT 推理任务中相较于基线的性能加速比。

设备库 (Device Libraries) 与 CUTLASS 3.0

NVIDIA 加速库分为主机库 (Host Libraries) 和设备库 (Device Libraries)。设备库可直接在 GPU 设备代码(Kernel)中调用,提供了更底层的编程灵活性。CUTLASS 是一个用于实现高性能矩阵运算的 C++ 模板库,是设备库中的一个关键组件。

Page 69, NVIDIA 加速库的架构,突出显示了设备库特别是 CUTLASS 的位置。
Page 69, NVIDIA 加速库的架构,突出显示了设备库特别是 CUTLASS 的位置。

CUTLASS 3.0

CUTLASS 3.0 是一个面向 CUDA 的线性代数核函数张量核心编程模型。

  • 主要特性:

    • 使用全新的 CuTe 库重写,CuTe 是一种用于线程和数据布局的健壮表示方法。
    • 使用平铺的 MMA(Matrix Multiply-Accumulate)和复制微内核(micro-kernels)来表示所有 GPU 架构的内部循环。
    • 允许开发者自由地将微内核与任何外部循环调度组合,为针对 Hopper 架构的自定义核函数开发提供了理想的抽象。
  • Hopper 架构支持:

    • 为 H100 中的第四代 Tensor Core 提供优化计算。
    • 提供针对 Hopper WGMMA + TMA + 线程块集群的 GEMM 核函数。
    • 通过 Warp 专用的持久化网格调度实现峰值利用率。
Page 70, CUTLASS 3.0 的主要特性以及单个 Hopper FP64 Tensor Core 操作的线程与数据布局示例。
Page 70, CUTLASS 3.0 的主要特性以及单个 Hopper FP64 Tensor Core 操作的线程与数据布局示例。

CuTe: 线程与数据布局的稳健表示

CuTe 是 CUTLASS 3.0 引入的全新编程模型和 API,旨在简化和统一内存布局的表示。它通过 Layout<Shape, Stride> 的统一定义取代了旧有的复杂定义,可同时用于表示线程和数据的布局。

Page 71, 从 CUTLASS 2.x 复杂的布局定义到 CUTLASS 3.0 CuTe 简洁布局定义的演变。
Page 71, 从 CUTLASS 2.x 复杂的布局定义到 CUTLASS 3.0 CuTe 简洁布局定义的演变。

CUTLASS 3: 改善开发者与用户体验

CUTLASS 3.0 通过简化但功能强大的核函数实例化,提升了开发体验。开发者可以通过修改单个参数来轻松切换 Hopper 优化的 GEMM 主循环调度策略。

Page 72, 展示了通过简单修改代码即可切换 CUTLASS 3 中 GEMM 核函数调度策略的示例。
Page 72, 展示了通过简单修改代码即可切换 CUTLASS 3 中 GEMM 核函数调度策略的示例。

CUTLASS 3.1(实验性)将引入 Python 接口,进一步降低使用门槛,实现从 Python 定义到与 PyTorch 等框架集成的自动化流程。

Page 73, CUTLASS 3.1 实验性 Python 接口的简化工作流程示意图。
Page 73, CUTLASS 3.1 实验性 Python 接口的简化工作流程示意图。

大规模开发与调试工具

NVIDIA GPU 计算工具

NVIDIA 提供了一套全面的 GPU 计算工具,帮助开发者在各个层面发现和解决问题。

  • 正确性工具 (Correctness Tools): 例如 compute-sanitizer,用于检查内存访问错误、未对齐访问、越界等问题。
  • 调试器、性能分析器、IDE 集成 (Debuggers, Profilers, IDE Integration): 提供代码级调试和性能瓶颈分析。
  • 系统性能分析与建议 (System Profiling, Analysis & Recommendation): Nsight Systems 等工具提供系统级的性能视图和优化建议。
  • 网络与通信采样 (Networking & Communications Sampling): 分析网络接口控制器(NIC)的吞吐量,并使用 NVTX 进行代码插桩以追踪通信模式。
  • 在线监控 (Online Monitoring (DCGM)): 实时监控 GPU 的功耗、温度、利用率等指标。
Page 74, NVIDIA GPU 计算工具生态系统的概览,包括正确性检查、调试、性能分析和监控等工具。
Page 74, NVIDIA GPU 计算工具生态系统的概览,包括正确性检查、调试、性能分析和监控等工具。

Nsight Systems 多节点分析

Nsight Systems 提供了强大的多节点分析功能,被称为“工具的工具”,用于处理大规模集群的性能数据。

  • 功能:
    • 分析现有报告的配方 (Recipes): 可以从多个来源或节点收集报告,减少了分析的启动时间。
    • 分析数千份报告: 支持规模化的处理能力,从而得出集群范围内的结论。
    • 生成多种格式的结果: 分析结果可以生成 Jupyter Notebook, Parquet, CSV 等多种格式,便于进一步处理和可视化。
Page 75, Nsight Systems 多节点分析功能介绍,适用于大规模集群环境。
Page 75, Nsight Systems 多节点分析功能介绍,适用于大规模集群环境。

多报告分析工作流 (Multi-Report Analysis Workflow)

该功能在 Nsight Systems 2023.2 版本中提供预览。其工作流包括设置与报告生成、启动分析、输出与可视化三个阶段。

  1. 设置与报告生成 (Setup & Report Generation): 用户选择或创建配方(Recipe),并在集群作业中与应用程序一起运行 Nsight Systems CLI,为每个节点生成报告。
    Page 76
  2. 启动分析 (Launch Analysis): 启动配方运行时(Nsys Recipe Runtime),利用 Dask 等框架在多个工作节点上并行处理多个报告。
    Page 77
  3. 输出与可视化 (Output & View): 分析结果可以保存为多种格式,并使用 Nsight Systems GUI 或 JupyterLab 进行查看和分析。
    Page 78

示例:热力图分析 (Example: Heatmap Analysis)

这是一个多报告分析的应用实例。通过热力图,可以直观地展示多节点工作负载在一段时间内的行为,如内核时间覆盖率和 SM 活动,有助于快速识别性能瓶颈和不平衡现象。

Page 79
Page 79

数据中心规模计算与安全

Page 80
Page 80

数据安全通常关注静态数据(Data at Rest)和传输中数据(Data in Transit)。然而,第三种状态——使用中数据(Data in Use)——的保护通常较弱,构成了重大风险。

Page 81
Page 82

什么是机密计算 (Confidential Computing)?

机密计算旨在解决“使用中数据”的保护问题,通过保护静态、传输中和使用中的数据,构成了端到端数据安全的关键一环。

  • 核心功能:
    • 保护数据和代码,防止其他用户访问。
    • 保护数据和代码,防止机器所有者(如云服务提供商)访问。
Page 83
Page 83

采用基于虚拟机的机密计算的 GPU

  • 机密计算关闭状态 (Confidential Computing: OFF): 在传统虚拟化环境中,Hypervisor(虚拟机监控程序)对所有系统内存和 GPU 内存拥有完全访问权限,数据传输是明文的。
    Page 84

  • 机密计算开启状态 (Confidential Computing: ON): 通过在 CPU 上创建可信执行环境(Trusted Execution Environment, TEE),部署一个机密虚拟机(Confidential VM)。Hypervisor 被阻止访问机密虚拟机的系统内存和 GPU 内存,且 CPU 和 GPU 之间的数据传输是加密的。
    Page 85

机密计算运行模式

  • 应用无需修改: 应用程序可以在机密模式下运行,无需任何代码更改。
  • 工作负载保护: 基于虚拟机的 TEE 保护整个工作负载。
  • GPU 隔离: 每个 GPU 通过直通(pass-through)方式分配给一个虚拟机,从而实现资源隔离。
Page 86
Page 86

在保密计算下未经修改运行CUDA应用程序

本节通过一系列图示,分步阐述了标准的CUDA应用程序工作流,并将其与在保密计算(Confidential Computing, CC)环境下的工作流进行对比,强调了在启用保密计算后,CUDA应用程序无需修改即可运行。

标准CUDA执行流程 (CC 关闭)

在标准的非保密计算环境中,一个典型的CUDA应用程序执行包含以下五个步骤:

  1. 分配GPU缓冲区:在GPU内存中为数据和结果分配空间。
  2. 在CPU上分配和初始化数据:在CPU的系统内存中分配空间(通常是锁页内存, Pinned sysmem)并初始化数据。
  3. 将数据从CPU复制到GPU:通过PCIe总线使用直接内存访问(DMA)将数据从CPU内存传输到GPU内存。

    Page 91: 标准执行流程 - DMA数据传输至GPU
    Page 91: 标准执行流程 - DMA数据传输至GPU
  4. 启动内核处理数据:在GPU上启动CUDA内核,对传输过来的数据进行计算。

    Page 92: 标准执行流程 - 启动内核
    Page 92: 标准执行流程 - 启动内核
  5. 将数据从GPU复制回CPU:计算完成后,通过DMA将结果从GPU内存传回CPU内存。

    Page 93: 标准执行流程 - DMA数据传回CPU
    Page 93: 标准执行流程 - DMA数据传回CPU

保密计算环境下的CUDA执行流程 (CC 开启)

在保密计算环境中,CPU及其内存运行在一个受保护的保密虚拟机(Confidential VM)或可信执行环境(Trusted Execution Environment, TEE)内,而GPU则位于该环境之外。尽管环境发生了变化,CUDA应用程序的执行流程对开发者而言保持不变。

Page 94: 保密计算环境示意图
Page 95: 可信执行环境(TEE)中的保密虚拟机

以下是在保密计算开启(CC On)的情况下,CUDA执行流程的对应步骤及其变化:

  1. 正常的GPU分配:与CC关闭时相同,在GPU内存中分配缓冲区。

    Page 96: CC开启流程 - 第1步:正常的GPU分配
    Page 96: CC开启流程 - 第1步:正常的GPU分配
  2. 受管分配与初始化:与CC关闭时使用锁页内存不同,CC开启时采用受管内存(Managed allocation)进行分配和初始化。数据位于受保护的CPU内存中。

    Page 97: CC开启流程 - 第2步:受管分配与初始化
    Page 97: CC开启流程 - 第2步:受管分配与初始化
  3. 加密的DMA传输:当数据通过PCIe总线从CPU传输到GPU时,传输过程是加密的,以保护数据在离开TEE后的机密性。

    Page 98: CC开启流程 - 第3步:加密的DMA传输至GPU
    Page 98: CC开启流程 - 第3步:加密的DMA传输至GPU
  4. 加密的内核启动:内核的启动指令和相关数据在传输和执行过程中也受到保护。

    Page 99: CC开启流程 - 第4步:加密的内核启动
    Page 99: CC开启流程 - 第4步:加密的内核启动
  5. 加密的DMA传输:计算结果从GPU传回CPU时,同样经过加密的DMA传输,确保结果数据在进入TEE之前保持机密。

    Page 100: CC开启流程 - 第5步:加密的DMA传输回CPU
    Page 100: CC开启流程 - 第5步:加密的DMA传输回CPU

核心优势在于,尽管底层增加了加密和解密等安全措施,但从开发者的角度来看,所使用的CUDA API(如cudaMalloc, cudaMemcpy, 内核启动语法)与标准环境完全相同,实现了应用程序代码的无缝迁移。

参考文献

Page 101: 参考文献列表
Page 101: 参考文献列表
  • S51120 Programming Model and Applications for the Grace Hopper Superchip
  • S51054 Accelerating HPC applications with ISO C++ on Grace Hopper
  • S51755 C++ Standard Parallelism
  • S51210 How to Write a CUDA Program
  • S51705 How to Streamline Shared Memory Space With the NVSHMEM Communication Library
  • S51789 cuNumeric and Legate: How to Create a Distributed GPU Accelerated Library
  • S51176 Recent Developments in NVIDIA Math Libraries
  • S51413 Developing Optimal CUDA Kernels on Hopper Tensor Cores
  • S51205 From the Macro to the Micro: CUDA Developer Tools Find and Fix Problems at Any Scale
  • S51421 Optimizing at Scale: Investigating and Resolving Hidden Bottlenecks for Multi-Node Workloads
  • S51709 Hopper Confidential Computing: How It Works under the Hood
  • S51684 Confidential Computing: The Developer's View to Secure an Application and Data on NVIDIA H100
  • S51074 A Deep Dive into the Latest HPC Software
  • S51880 A Demonstration of AI and HPC Applications for NVIDIA Grace CPU
  • CWES52036 Connect with the Experts: What's in Your CUDA Toolbox? CUDA Profiling, Optimization, and Debugging Tools for the Latest Architectures
  • Whitepaper NVIDIA Grace Hopper Superchip Architecture
  • Blog CUDA 12.0 Compiler Support for Runtime LTO Using nvJitLink Library
  • Package Download MathDx Today
  • Repo Download CUTLASS 3.0 from the GitHub repo