GPU到底如何做到这么快的?
HPC沿Nvidia CUDA-GPU架构走。 从零到如今。
有人将机器学习定义为数学(算法),工程学(高性能计算)和人类能力(经验)之间的完美融合。 因此,这些领域中的任何进展都将有助于机器学习的发展。 今天是HPC的转折点,特别是我们在谈论GPU的进步。
Nvidia刚刚宣布了基于Ampere架构的Geforce RTX 30系列(RTX3090,RTX3080,RTX3070)。 Ampere是我们最喜欢的GPU品牌的最新架构,但是到目前为止已经发布了几代具有CUDA功能的GPU。 在以下各段中,我将描述从今天开始到今天的CUDA架构的全球概述,让我们一起推动一条有趣的路,从费米到安培。 但是,在不进一步了解细节之前,强烈建议您访问以前关于CUDA执行模型的文章,如果您不熟悉GPU计算的话。
遵循Nvidia GPU的自然发展时间表,该公司于2001年首次生产了能够进行可编程着色的芯片GeForce 3,该芯片被Playstation 2和Xbox所使用。 在GeForce 3(代号NV20)之前,还有其他一些产品:NV1(1995),NV3(1997),NV4(1998),NV5(1999),GeForce I(1999年末)和GeForce II(2000)。 但是,GeForce 3可能是第一个流行的Nvidia GPU。
指出Nvidia世界中目标类别和体系结构之间的差异很有趣,这可能会使读者感到困惑。 传统上,Nvidia为每种目标客户类别设计不同类型的产品,并命名为四个不同的产品:GeForce,Quadro,Tesla和(最近)Jetson。 尽管内部使用的底层体系结构对于这四个产品都是相同的。 用Nvidia话来说,它们四个具有相同的计算能力。 GeForce系列产品主要针对台式机和游戏玩家。 Quadro被认为是创建视频内容的工作站和开发人员的工具; 而Tesla是为超级计算机和HPC设计的。 最后,Jetson系列包含芯片中的嵌入式GPU。
正如我们在上面看到的那样,Nvidia在90年代初就开始了冒险,其GPU专注于grapichs,但是我们一直等到2007年才使用第一个CUDA架构:Tesla(是的,您是对的,他们使用相同的架构名称 稍后是一条产品线,这就是为什么我说这可能会造成混淆)。 Tesla是一个非常简单的体系结构,因此我决定直接从Fermi开始,它引入了Error-Correcting Code内存,确实改善了上下文切换,内存层次结构和双精度。
费米架构
每个Fermi流多处理器(SMI)均有32个CUDA内核(流处理器),16个加载/存储单元(LD / ST单元)组成,每个时钟可处理16个线程的内存操作,并具有4个特殊功能单元(SFU)以执行超越数学 指令,内存层次结构和翘曲调度程序。
> Fermi Streaming Multiprocessor (Image by author)
该板有6个64位内存分区和384位内存接口,最多可支持6 GB的GDDR5 DRAM内存。 CPU通过PCI-e总线连接到GPU。 每个CUDA内核都有一个完整的流水线算术逻辑单元(ALU)和一个浮点单元(FPU)。 为了执行双精度,32个CUDA内核可以用作16个FP64单元。 每个SM具有两个warp调度程序,这些调度程序可启用发布并同时执行2个warp。
该体系结构的关键模块是内存层次结构。它引入了64 KB的可配置共享内存和每个SM的L1缓存,可以将其配置为16 KB的L1缓存和48 KB的共享内存。或16 KB共享内存和48 KB L1缓存。尽管CPU L1缓存是针对空间和时间局部性而设计的,但GPU L1仅针对空间局部性进行了优化。频繁访问缓存的L1内存位置不会增加命中数据的可能性,但是当多个线程正在访问相邻的内存空间时,这很有吸引力。 768 KB L2缓存是统一的,并在为所有操作(加载,存储和纹理)提供服务的所有SM之间共享。这两个缓存均用于将数据存储在本地和全局内存中,包括寄存器溢出。但是,必须配置是在L1和L2中还是仅在L2中缓存读取。此体系结构表示为计算能力2.x,这是Nvidia的特殊术语,用于描述GPU的硬件版本,该硬件版本包括主修订号(左数字)和次修订号(右数字)。具有相同主要修订版本号的设备属于相同的核心体系结构,而次要修订版本号对应于对核心体系结构的增量改进。
> Fermi Memory Hierarchy (Image by author)
开普勒架构
开普勒包括多达15个SM和六个64位存储器控制器。 每个SM具有192个单精度CUDA内核,64个双精度单元,32个SFU,32个LD / ST单元和16个纹理单元。
> Kepler Streaming Multiprocessor (Image by author)
另外,四个warp调度程序每个都有两个调度单元,它们允许同时发布和执行四个warp。 它还将每个线程访问的寄存器数量从Fermi中的63个增加到255个; 它引入了改组指令,并通过在全局内存中引入对FP64原子的本机支持来改进原子操作。 它还介绍了CUDA动态并行,即从内核启动内核的能力。 此外,内存层次结构与Fermi相似。
> Kepler Memory Hierarchy (Image by author)
通过允许在L1缓存和共享内存之间分割32 KB / 32 KB,改进了64 KB共享内存/ L1缓存。 它还将共享内存库的宽度从Fermi中的32位增加到64位,并引入了48 KB只读数据缓存来缓存常量数据。 L2缓存也增加到1536 KB,使Fermi L2缓存容量增加了一倍。 此外,开普勒计算功能由3.x代码表示。
麦克斯韦架构
Maxwell最多包含16个SM和四个内存控制器。 每个SM已重新配置以提高每瓦性能。 它包含四个Warp调度程序,每个调度程序每个时钟周期可以为每个warp调度两个指令。 SM分为四个32-CUDA核心处理模块,每个模块具有八个纹理单元,8个SFU和8个LD / ST单元。
> Maxwell Streaming Multiprocessor (Image by author)
关于内存层次结构,它具有96 KB的专用共享内存(尽管每个线程块最多只能使用48 KB),而L1缓存与纹理缓存功能共享。 L2缓存提供2048 KB的容量。 内存带宽也增加了,从开普勒的192 GB /秒增加到了224 GB /秒,并且为共享内存中的FP32原子引入了本机支持。 Maxwell表示为计算能力5.x。
> Maxwell Memory Hierarchy (Image by author)
帕斯卡架构
一个Pascal板由多达60个SM和8个512位存储器控制器组成。 每个SM具有64个CUDA核心和四个纹理单元。 它具有与Kepler和Maxwell相同数量的寄存器,但是提供了更多的SM,因此总体上有更多的寄存器。 它被设计为支持比以前的体系结构更多的活动扭曲和线程块。 共享内存带宽加倍,以更高效地执行代码。 它允许加载/存储指令的重叠以增加浮点利用率,还改善了warp调度,其中每个warp调度程序都能够在每个时钟上调度两个warp指令。 CUDA内核能够处理16位和32位指令和数据,从而促进了深度学习程序的使用,而且还为数字程序提供了32个FP64 CUDA内核。 全局内存本机支持也已扩展为包括FP64原子。
> Pascal Streaming Multiprocessor (Image by author)
内存层次结构配置也已更改。 每个内存控制器都连接到512 KB的L2缓存,提供4096 KB的L2缓存,并引入了HBM2内存,提供了732 GB / s的带宽。 它为每个SM提供64 KB的共享内存,以及一个L1高速缓存,该L1高速缓存也可以用作纹理高速缓存,该纹理高速缓存用作合并缓冲区以增加扭曲数据的局部性。 它的计算能力由6.x代码表示。
> Pascal Memory Hierarchy (Image by author)
最后,介绍了NVLink技术。 背后的想法是,任何4-GPU和8-GPU系统配置都可以解决相同的问题。 甚至,使用InfiniBand®和100 Gb以太网将几组多GPU系统互连在一起,以形成更大,功能更强大的系统。
伏打架构
一块Volta板上最多可包含84个SM和八个512位内存控制器。 每个SM具有64个FP32 CUDA内核,64个INT32 CUDA内核,32个FP64 CUDA内核,8个用于深度学习矩阵算术的张量内核,32个LD / ST单元,16个SFU。 每个SM分为4个处理块,每个块包含一个新的L0指令高速缓存,以提供比以前的指令缓冲区更高的效率以及带有调度单元的warp调度程序,这与Pascal的2分区设置相反,每个子核心warp都有两个调度端口 调度程序。 这意味着Volta失去了在单个时钟周期内从线程发出第二条独立指令的能力。
> Volta Streaming Multiprocessor (Image by author)
引入了合并的128 KB L1数据高速缓存/共享内存,提供了96 KB的共享内存。 HBM2带宽也得到了提高,获得900 GB / s。 此外,完整的GPU总共包括6144 KB的L2缓存,其计算能力由7.0代码表示。
> Volta Memory Hierarchy (Image by author)
但是,最大的变化来自其独立的线程调度。 以前的体系结构以SIMT方式执行扭曲,在32个线程之间共享一个程序计数器。 在发生分歧的情况下,活动掩码指示在任何给定时间哪些线程处于活动状态,而使某些线程保持不活动状态并针对不同的分支选项序列化执行。 Volta包括一个程序计数器和每个线程的调用堆栈。 它还引入了调度优化程序,该调度程序确定必须将来自同一线程束的哪些线程必须一起执行到SIMT单元中,从而提供更大的灵活性,因为线程现在可以以子线程束粒度分散。
Volta的最新突破功能称为Tensor Core,与以前的Pascal P100加速器相比,它在深度学习应用中的速度提高了12倍。 它们本质上是混合精度FP16 / FP32内核的阵列。 640个张量核中的每个核都在4x4矩阵上运行,并且它们的关联数据路径是自定义设计的,以提高此类矩阵上运算的浮点计算吞吐量。 每个张量核心每个时钟执行64个浮点融合乘加(FMA)操作,为训练和推理应用提供多达125 TFLOPS。
此外,第二代NVLink为多GPU系统配置提供了更高的带宽,更多的连接和改进的可伸缩性。 与GP100上的4NVLink链接和160 GB / s的总带宽相比,Volta GV100最多支持6条NVLink链接和300 GB /秒的总带宽。
图灵(不是全新的)架构
NVIDIA首席执行官黄仁勋(Jen-Hsun Huang)对Pascal,Volta和Turing之间的架构差异提供了有趣的答复。 他基本上解释说,Volta和Turing具有不同的目标市场。 Volta适用于大规模培训,最多可连接八个GPU,具有最快的HBM2,以及其他专门用于数据中心的功能。 另一方面,图灵在设计时考虑了三个应用程序:专业可视化,视频游戏和使用Tensor Core的图像生成。 实际上,图灵具有与Volta 7.x相同的计算能力,这就是为什么我说图灵不是一种全新的体系结构。
最杰出的成就是:使用GDDR6内存并引入了RT内核,这些RT内核可以渲染逼真的3D游戏和复杂的专业模型:
> Turing Streaming Multiprocessor. Source:NVIDIA
像Volta一样,Turing SM被分为4个处理块,每个处理块都有一个单独的warp调度程序和调度单元。 图灵与Volta在两个周期内执行指令几乎相同,但其调度程序可以在每个周期内发出独立的指令。 此外,Volta和Turing并非像Pascal这样的按线程分配,而是具有按线程调度的资源,它具有程序计数器和按线程堆栈的功能来跟踪线程状态。
安培架构
最新的CUDA架构称为Ampere,可提供迄今为止最高的GPU性能。 我强烈建议其他人在这里进行了非常完整的审查。
每个Ampere SM包含四个处理块,每个处理块具有用于数据缓存的L0高速缓存,一个扭曲调度程序,16个INT32 CUDA内核,16个FP32 CUDA内核,8个FP64 CUDA内核,8个LD / ST内核,用于矩阵乘法的Tensor内核以及一个 16K 32位寄存器文件。 每个SM具有192 KB的组合共享内存和L1数据缓存; 在GPU级别,它具有40MB的二级缓存以提高性能(比Volta中的V100大7倍)。 L2缓存分为两个分区以实现更高的带宽。
> Ampere Streaming Multiprocessor. Source: NVIDIA.
GA100 GPU芯片由128个SM组成,但是主要是因为-行销-制造,所以不同的Ampere GPU将仅支持其中的一些。 例如,A100 GPU仅公开108个SM。 无论如何,完整的GA100由8个GPC组成,每个GPC具有16个SM和6个HBM2堆栈。 对于A100 GPU,这将以1555 GB / s的速度转换为40 GB的HBM2 DRAM内存。
它还引入了第三代NVIDIA Tensor内核(仅次于Volta和Turing),使其能够计算每个时钟8×4×8混合精度矩阵乘法(将8×4矩阵与4×8矩阵相乘)。 例如,每个A100 Tensor Core每个时钟执行256个FP16 FMA(融合乘加)操作。 Ampere在其Tensor Core上支持许多数据类型,包括FP16,BF16,TF32,FP64,INT8,INT4和Binary。
最后,在Ampere上展示了第三代NVLink。 对于A100 GPU,它具有12条NVLink链接,总带宽为600 GB / s,用于进行多GPU计算。 关于PCIe连接,A100 GPU支持PCIeGen 4,它提供每个方向31.5 GB /秒的带宽(对于x16连接),使PCIe 3的带宽增加了一倍。
参考文献
费米白皮书
开普勒白皮书
麦克斯韦白皮书
帕斯卡白皮书
伏打白皮书
图灵白皮书
安培白皮书
GPU上的并行算法
(本文翻译自Adrian PD的文章《How the hell are GPUs so fast? A HPC walk along Nvidia CUDA-GPU architectures. From zero to nowadays.》,参考:https://towardsdatascience.com/how-the-hell-are-gpus-so-fast-a-e770d74a0bf)