广州档案馆建设网站,seo关键字优化技巧,线上建模培训班哪个好,让客户留住更长时间访问你的网站Modeling Deep Learning Accelerator Enabled GPUs 发表在 ISPASS 2019 上。文章研究了 NVIDIA 的 Volta 和 Turing 架构中张量核的设计#xff0c;并提出了 Volta 中张量核的架构模型。 基于 GPGPU-Sim 实现该模型#xff0c;并且支持 CUTLASS 运行。发现其性能与硬件非常吻…Modeling Deep Learning Accelerator Enabled GPUs 发表在 ISPASS 2019 上。文章研究了 NVIDIA 的 Volta 和 Turing 架构中张量核的设计并提出了 Volta 中张量核的架构模型。 基于 GPGPU-Sim 实现该模型并且支持 CUTLASS 运行。发现其性能与硬件非常吻合与 Titan V GPU 相比获得了99.6%的 IPC 相关性。文中还展示了 Turing 架构中张量核的操作数矩阵元素到线程的映射并发现它们与 Volta 张量核的行为不同。
Related Work
论文的相关工作 Demystifying GPU Microarchitecture through Microbenchmarking 使用广泛的微基准对 NVIDIA GT200进行了透彻的分析。他们探索了处理核和内存层次结构的架构细节。描述了先前未公开的屏障同步和内存层次结构的细节包括 GPU 中的 TLB 组织。 Dissecting the NVIDIA Volta GPU Architecture via Microbenchmarking 详细研究了张量核。他们在混合精度模式下解码了 Volta 张量核的集合和步骤。 NVIDIA Tensor Core Programmability, Performance Precision 研究了 Tensor Core 的精度损失和可编程性方面对 HPC 应用的影响。 Exploring Modern GPU Memory System Design Challenges through Accurate Modeling 研究了包括 Volta 在内的现代 GPU 的内存系统并发现了内存系统中许多重要的设计决策。他们在 GPGPU-Sim 中对其进行建模并在广泛的 GPGPU 工作负载上实现了非常高的相关性。
Background
Volta Microarchitecture
Volta 是 NVIDIA 第一代包含机器学习加速器的 GPU 架构。NVIDIA GPU 通常由多个流式多处理器 (Streaming Multiprocessor, SM) 组成这些处理器通过片上网络连接到多个内存分区。 每个内存分区都包含最后一级缓存的一部分并将 GPU 连接到片外 DRAM。 正如 NVIDIA 所描述的每个 SM 内包含多个张量核。Volta 中的 SM 设计分为四个处理块NVIDIA 将其称为 Sub-Core。如图 1所示Volta 中的每个子核都有两个张量核、一个 Warp 调度器、一个调度单元和一个64KB 的寄存器文件。 除了新增张量核之外Volta 还包括与机器学习工作负载性能相关的其他增强功能
每个流式多处理器 (SM) 的调度单元数量是上一代 Pascal 架构的两倍拥有独立的整数和 32 位浮点 (FP32) 核对发散线程分支后面的两条路径都可以由单个 warp 内的线程以交错的方式执行。
Tensor Core
每个张量核都是一个可编程计算单元专门用于加速机器学习工作负载。Tesla Titan V GPU 包含分布在80个 SM 中的640个张量核每个 SM 有8个张量核在1530 MHz 的工作频率下提供125 TFLOPS 的理论性能。根据 NVIDIA TESLA V100 GPU ARCHITECTURE每个张量核可以在每个时钟周期完成一次 4 × 4 4\times 4 4×4 矩阵乘法累加 (MACC)即 D A × B C DA\times BC DA×BC其中 A , B , C A ,B,C A,B,C 是 4 × 4 4\times 4 4×4 矩阵如图 3 所示。
虽然单个张量核在任何时候都对 4 × 4 4 \times 4 4×4 矩阵进行操作但 WMMA API 在更大的图块大小上公开张量核。自然地两个 16 × 16 16 \times 16 16×16 矩阵的乘法分解为一个分块矩阵乘法结果矩阵由十六个 4 × 4 4 \times 4 4×4 子矩阵构成每个涉及四个 4 × 4 4 \times 4 4×4 矩阵相乘累加。因此CUDA C WMMA 级别的每个mma_sync或 PTX 级别的每个 wmma.mma操作可以用64个独立的张量核操作来实现。
张量核有 FP16 和混合精度两种工作模式
在 FP16模式下张量核读取三个 4 × 4 4 \times 4 4×4 16位浮点矩阵作为源操作数而在混合精度模式下它读取两个 4 × 4 4 \times 4 4×4 16位浮点矩阵以及第三个 4 × 4 4 \times 4 4×4 32位浮点累加矩阵。
Demystifying NVIDIA’s Tensor Cores
Dissecting the NVIDIA Volta GPU Architecture via Microbenchmarking 研究了列主布局中混合精度模式的矩阵操作数元素到寄存器的分布情况。文中将线程束内的一组四个连续线程称为“线程组”。
为了描述方便论文余下部分中将其缩写为 threadgroup。由于一个 warp 中有32个线程因此一个线程束中有 8 8 8 个 threadgroup。给定线程的 threadgroup id类似于 Dissecting the NVIDIA Volta GPU Architecture via Microbenchmarking 中的“group id”根据 ⌊ t h r e a d I d x 4 ⌋ \lfloor\frac{threadIdx}{4}\rfloor ⌊4threadIdx⌋ 得到。
Microbenchmarks
本节讨论了用于分析张量核实现的微基准测试。其包含两种类型的微基准测试
一种旨在确定数据如何移入和移出张量核另一种用于确定张量核执行操作所需的时间。
Fragment to thread mapping
图 4包含 III-B 节中使用的 CUDA 代码的一部分用于确定操作数矩阵元素和线程之间的映射。此代码是在 16 × 16 16\times16 16×16 矩阵上运行的更大的通用矩阵乘法 (GEMM) 内核的一部分。每个线程加载输入矩阵的一个段并将其打印到输出控制台。通过使用不同的值初始化输入矩阵的每个元素可以直接揭示从操作数矩阵元素到线程束内线程的映射。
Analyzing machine instructions
正如在 III-C. Machine ISA interface 节中详细描述的那样PTX 指令被映射为多个HMMA SASS 指令。图 5 在高层次上说明了用微基准测试分析HMMA指令如何访问数据时的操作。作者使用 radare2 将HMMA操作替换为“无操作” ( NOP) 指令的操作仅保留一个HMMA操作。
图 6 概括地说明了微基准测试用于分析张量核心上低级操作的时序的方法。为了开发这些微基准测试作者使用 radare2 添加了在 1 s t 1^{st} 1st 之前和 n t h n^{th} nth HMMA指令之后读取时钟寄存器的代码。
Operand matrix element mapping
本节总结了矩阵元素到线程的分布的分析结果。
Volta Tensor Cores
图 7a 和 7b 总结了矩阵操作数的元素如何映射到线程束内各个线程的寄存器。
大矩形 ( 1 ◯ \textcircled{1} 1◯) 表示 FP16和混合精度操作模式的 16 × 16 16\times16 16×16 操作数矩阵 A 或 B。较小的方块是操作数矩阵中的各个元素同一行中的元素在内存中连续存储。每个 threadgroup 加载一个不同的 4 × 16 4\times16 4×16 子矩阵文中将其称为一个段。组成操作数矩阵的四个段用不同的着色突出显示。 图 7a 的右上部分 ( 2 ◯ , 3 ◯ \textcircled{2},\textcircled{3} 2◯,3◯) 显示了段内的元素如何分布在一个线程组的线程中。在 Volta 上每个段都由两个不同的 threadgroup 加载。因此A 和 B 操作数矩阵的每个元素 由 Volta 上的线程束中的两个不同线程加载。图 7a 的底部部分 ( 4 ◯ \textcircled{4} 4◯) 与左上角部分 ( 1 ◯ \textcircled{1} 1◯) 相结合总结了确切的映射。例如实验发现操作数矩阵 A 的连续前四行由 threadgroup 0和2加载。
以行优先布局存储的操作数矩阵 A 的矩阵元素到线程的分布与以列优先布局存储的操作数矩阵 B 的分布相同反之亦然。
对于行主布局中的操作数矩阵 Athreadgroup 内的每个线程使用两个合并的 128 位宽加载指令加载一行中的 16 16 16 个连续元素 ( 2 ◯ \textcircled{2} 2◯)而在列主布局中为了加载4行 threadgroup 内的每个线程通过四个合并的 64 位宽加载指令加载四个块每个块内四个连续元素每个加载指令的跨距为 64 个元素 ( 3 ◯ \textcircled{3} 3◯)。
如图 7b 所示对于操作数矩阵 C矩阵元素到线程的分布是不同的。具体来说
对于操作数矩阵 C每个 threadgroup 加载矩阵 C 的一个 8 × 4 8\times 4 8×4 段。threadgroup 内的具体分布取决于矩阵 C 是 FP16还是 FP32并且与布局无关。
在两种工作模式下均使用32位宽部分合并的加载指令访问矩阵 C 的元素。
Turing Tensor Cores
图 8 总结了 NVIDIA Turing 架构中张量核的操作数矩阵元素到线程的分布。Turing 的张量核心支持三种新的精度模式1位、4位和8位以及三种新的图块大小8位和16位模式的 32 × 8 × 16 32\times 8\times 16 32×8×16 和 8 × 32 × 16 8\times 32\times 16 8×32×164位模式为 8 × 8 × 32 8\times 8\times 32 8×8×32。 Figure 8: Distribution of operand matrix elements to threads for tensor cores in the RTX 2080 (Turing).
在撰写本文时对1位模式的支持才启用并且似乎不适用于文中的系统。因此本文其余部分不提供1位模式的分析。
Turing 的元素到线程的分布比 Volta 更简单。具体而言
每个操作数矩阵元素仅加载一次。两种图块尺寸 32 × 8 × 16 32\times 8\times 16 32×8×16 和 8 × 32 × 16 8\times 32\times 16 8×32×16 都采用相同的分布。对于所有模式和配置每行或列取决于模式和操作数矩阵由 threadgroup 加载并且连续的 threadgroup 加载连续的行或列。
Machine ISA interface
本节总结了作者所了解的有关如何在机器指令集架构级别访问 Tensor Core 的知识。 对于 NVIDIA GPU这个层次通常称为 SASS。这里的分析基于使用 NVIDIA 的 cuobjdump 工具检查 SASS 反汇编。
论文发现wmma.load和wmma.store PTX 指令是通过分解为一组普通的 SASS 加载LD.E.64、LD.E.64、LD.E.SYS 和存储 (ST.E.SYS) 指令来实现的。这表明 Tensor Core 直接从普通 GPU 寄存器文件中访问操作数矩阵片段。更详细地说发现wmma.load.c PTX 指令被分解为一组LD.E.SYS指令。
对于操作数矩阵 A 和 B根据操作数矩阵布局是行优先还是列优先将wmma.load PTX 指令拆分为四个 64 位加载 (LD.E.64) 或两个 128 位负载 (LD.E.128)。
图 9 说明了单个wmma.mma PTX 指令所对应的 Volta 的 SASS 代码。 从图中可以看出
矩阵乘法累加运算是通过新的 SASS 指令HMMA实现的。每个HMMA指令有四个操作数每个操作数使用一对寄存器。由不同内存操作访问的一对相邻寄存器使用单个寄存器标识符编码在HMMA指令中通过比较HMMA以及加载和存储使用的寄存器可以推断出。例如论文分析图 9 中第一条HMMA指令中的R8表示寄存器对R8R7。寄存器对中较高位的寄存器标识符是指令中编码的寄存器标识符。例如对于图 9 第一行的HMMA指令目标寄存器R8实际上代表R8,R7对。 类似地剩余的寄存器标识符实际上代表三对源操作数寄存器R24,R23、R22,R21和R8, R7。一些寄存器在图 9 中用“reuse”注释。 SGEMM Implementation 分析了 NVIDIA 针对早期 Maxwell 架构的 SASS 指令集其中经常出现类似的注释。根据他的分析和 NVIDIA 关于 GPU 寄存器文件缓存的相关论文[43]作者认为“reuse”符号表示相关操作数在下一步中被重用因此缓存在操作数重用缓存以避免寄存器读取并可能减少 bank冲突。
Volta Tensor Cores
每个wmma.mma PTX 指令被分解为一组HMMA指令
图 9a 说明了混合精度模式的 SASS 代码。在该模式下 每条 PTX wmma.mma指令被分解成16条HMMA指令。16条HMMA指令被组织为4条HMMA指令的4个集合。每条HMMA指令用 STEPn标注其中n的取值范围从0到3。因此每个集合包括四个步骤。 图 9b 说明了 FP16 模式的 SASS 代码其中 单条 PTX wmma.mma指令分为四组仅包含 2 个步骤。
图 9 还显示了 Volta Tensor Core 的累积时钟周期。wmma.mma API 在混合精度模式下的延迟比 FP16模式下低十个周期。
Turing Tensor Cores
对于 Turing每条 PTX wmma.mma指令
在4位模式下转换为单条HMMA指令其他模式下均都分为一组四个HMMA指令。
表 I 显示了 Turing 架构上HMMA指令的累积时钟周期。 对于 16 × 16 × 16 16\times 16\times 16 16×16×16 图块大小Turing 上混合精度模式下 wmma.mma的延迟为99个周期表 I 多于 Volta 的54个周期图 9a。混合精度模式的延迟大于 FP16模式。8位模式速度最快。4位模式的延迟最高这可能是因为它是2080 RTX 上的一个实验特性。
HMMA Instruction Analysis
本节将更详细地探讨HMMA执行。
Volta
作者考察了图 9 中HMMA指令的每个集合的操作。如图 10a 所示无论模式如何当执行集合中的HMMA指令时每个 threadgroup 将操作数矩阵 A 的 4 × 4 4\times4 4×4 图块与操作数矩阵 B 的 4 × 8 4\times 8 4×8 图块相乘并将结果与操作数矩阵 C 相加。例如当 threadgroup 0 执行第一组HMMA指令 (Set 1) 时它将由操作数矩阵 A 的前四行和前四列组成的子图块与由操作数矩阵 B 的前四行和前八列组成的子图块相乘。结果通过操作数矩阵 C 的 4 × 8 4\times8 4×8 子图块进行累加并存储在操作数矩阵 D 的 4 × 8 4\times8 4×8 子图块中。串联4个集合threadgroup 0 完成操作数矩阵 A 的 4 × 16 4 \times 16 4×16 图块与操作数矩阵 B 的 16 × 8 16 \times 8 16×8 图块的乘法。
图 10b 显示了混合精度模式下 threadgroup 0 的“集合”中每个HMMA “步骤”的详细操作。HMMA指令的每个“集合”包含四个“步骤”。在每个步骤中操作数矩阵 A 的 2 × 4 2\times4 2×4 子图块与操作数矩阵 B 的 4 × 4 4\times4 4×4 子图块相乘并与操作数矩阵 C 的 2 × 4 2\times4 2×4 子图块累加。
类似地图 10c 显示了 FP16模式下 threadgroup 0 的“集合”中每个HMMA“步骤”的详细操作。每组HMMA指令包含两个“步骤”。在每个步骤中每个线程组将操作数矩阵 A 的 4 × 4 4\times4 4×4 子图块与操作数矩阵 B 的 4 × 4 4\times4 4×4 子图块相乘并将结果与矩阵 C 累加。
经过以上步骤threadgroup 0 完成操作数矩阵 A 的 8 × 4 8\times4 8×4 子图块与操作数矩阵 B 的 4 × 8 4\times8 4×8 子图块的乘法。
Turing
图 11 说明了 Turing GPU 架构上HMMA指令访问的元素。 Volta 中HMMA SASS 指令上发现的“step”注释在 Turing 中不存在。 考虑到表 I 中的延迟结果并不表明并行性增加一种可能性是类似的“步骤”由微体系结构使用状态机排序。作者认为
对于不同的图块配置特定模式访问的元素是相似的。在 FP16 和混合精度模式下计算模式是两个子图块之间的乘积其中一个子图块是 8 × 8 8\times 8 8×8另一个子图块是 16 × 8 16\times 8 16×8 或 8 × 16 8\times 16 8×16。 例如对于图块大小 16 × 16 × 16 16\times 16\times 16 16×16×16 或 32 × 8 × 16 32\times 8\times 16 32×8×16SET 1 中的计算是矩阵 A 的 16 × 8 16\times 8 16×8 子图块与矩阵 B 的 8 × 8 8\times 8 8×8 子图块之间的乘积而对于图块大小 8 × 32 × 16 8\times 32\times 16 8×32×16乘积在矩阵 A 的 8 × 8 8\times 8 8×8 子图块与矩阵 B 的 8 × 16 8\times 16 8×16 子图块之间。对于8位模式计算模式为矩阵 A 的 8 × 16 8\times16 8×16 子图块与矩阵 B 的 16 × 8 16\times8 16×8 子图块之间的乘积。
在4位模式下每个 wmma.mma PTX 指令都是用单个HMMA SASS 指令实现的因此在图 11 中省略了4位模式。
Discussion
本节对上面给出的 Volta 结果进行分析并推断出将执行分解为“集合”和“步骤”的可能理由。
回想一下输入矩阵的每个元素都由两个不同的 threadgroup 加载。作者编写了一个微基准测试来帮助确定HMMA指令如何使用不同线程加载的片段。例如为了确定如何使用由 thread 0 加载的操作数矩阵元素作者更改了这些值并观察结果如何受到影响。论文发现 threadgroup 成对工作以计算结果的 8 × 8 8\times8 8×8 子图块并将每对这样的线程组称为 octet。一个线程束中有四个 octet。
表 II 显示了构成每个 octet 的 threadgroup 对一般可以表示为 o c t e t X t h r e a d g r o u p X ⋃ t h r e a d g r o u p X 4 \mathrm{octet}\, X \mathrm{threadgroup}\, X \bigcup\mathrm{threadgroup}\, X4 octetXthreadgroupX⋃threadgroupX4其中 X X X 介于 0 到 3 之间。表 II 还使用符号[Row_Start: Row_End, Col_Start: Col_End]来表示每个 threadgroup 内的线程访问的操作数矩阵 A 和 B 的子图块。无论操作数矩阵的存储布局如何threadgroup 加载的元素都保持不变。
表 II 显示操作数矩阵 A 和 B 的每个元素被不同 threadgroup 中的线程加载两次。这使得每个 octet 能够独立工作。具体来说每个 octet 读取操作数矩阵 A 的 8 × 16 8\times 16 8×16 子图块、操作数矩阵 B 的 16 × 8 16\times 8 16×8 子图块和操作数矩阵 C 的 8 × 8 8\times 8 8×8 子图块如图 12a 所示。 为了更好地理解 octet 中线程的组织作者分析了 octet 在不同“集合”和“步骤”中执行的计算。如图 12b 所示在每个集合中每个 octet 执行输入子图块之间的外积。例如在 Set 1 中完成输入子图块 [ a ] , [ e ] [a],[e] [a],[e] 和 [ A ] , [ E ] [A],[E] [A],[E] 之间外积生成部分结果 [ a A ] , [ a E ] , [ e A ] [aA], [aE], [eA ] [aA],[aE],[eA] 和 [ e E ] [eE] [eE]。这里每个 [ a ] , [ e ] , [ A ] , [ E ] [a],[e],[A],[E] [a],[e],[A],[E] 代表一个 4 × 4 4 \times 4 4×4 子图块。为了计算 [ a E ] [aE] [aE]threadgroup 0 需要操作数矩阵 B 子图块 [ E ] [E] [E]它仅由 threadgroup 4 加载。类似地要计算 [ e A ] [eA] [eA]threadgroup 4 需要操作数矩阵 B 子图块 [ A ] [A] [A]它仅由 threadgroup 0 加载。因此虽然 threadgroup 不能但 octet 可以独立工作。表 III 在图 12b 的基础上进行了扩展将在不同集合和步骤中执行的所有外积计算制成表格。
A Tensor Core Microarchitecture
本节提出了一个张量核微架构其与本文前面对 Volta 的观察结果一致。
回想一下每个张量核每个周期完成 4 × 4 4\times4 4×4 矩阵乘法并累加。 为了实现这一目标每个张量核必须能够在每个周期执行16个四元素点积four-element dot-productsFEDP。如图 9 和 图 10b 所示在稳定状态下 threadgroup 需要两个周期来生成输出矩阵的 2 × 4 2\times 4 2×4 子图块。 因此在 warp 内的所有线程中HMMA指令每个周期执行32个 FEDP。由于每个张量核每个周期只能完成16个 FEDP因此 SM 中每个子核需要两个张量核才能达到满吞吐量。为了证实这一点作者编写了一个微基准测试它重复执行HMMA操作改变每个线程块内的 warp 数量并保持并发执行的线程块数量不变。如图 12c 所示该微基准测试显示单个 SM 上只能同时执行 4 个 warp但 Titan V SM 每个 SM 有 8 个张量核。 因此每个 warp 似乎都利用了两个张量核。
接下来考虑寄存器访问带宽。图 9a 中的数据表明HMMA指令的最小启动间隔是两个周期。有三个源操作数并且如第 III-C 节中所述对于每个源操作数读取一对32位寄存器。综合考虑这些因素总寄存器读取带宽为每个线程束每两个周期 32 × 2 × 3 × 32 6 k b 32\times2\times3\times32 6\mathrm{kb} 32×2×3×326kb。 此带宽足以让线程束每两个周期获取以下值
操作数 A 的八个 2 × 4 2\times4 2×4 FP16子图操作数 B 的八个 4 × 4 4\times4 4×4 FP16子图以及操作数 C 的八个 2 × 4 2\times4 2×4 FP32子图或八个 4 × 4 4\times4 4×4 FP16子图。
假设每个线程束访问两个张量核每个张量核的寄存器带宽为每个时钟周期每个线程束1.5kb。
NVIDIA 指出在 Volta 中 INT 和 FP32指令可以共同下发[26]。另一方面Dissecting the NVIDIA Volta GPU Architecture via Microbenchmarking 报告张量核运算不能与整数和浮点算术指令共同发出。 论文认为原因是张量核可能正在使用与 INT 和 FP32核关联的寄存器文件访问端口。Titan V SM 内部有64个 INT 和64个 FP32 ALU共计128个 ALU。由于一个 SM 中的8个张量核共享对寄存器文件的访问权限每个张量核每个周期应该能够访问每个源操作的 128 8 × 32 16 × 32 512 \frac{128}{8}\times3216\times32512 8128×3216×32512 比特。假设每个 ALU 有3个源操作数以支持乘法累加运算这意味着每个张量核可以访问1.5kb/cycle。
图 13 展示了论文提出的张量核微架构。每个线程束使用两个张量核。假设线程束内每个张量核经由两个不同的 octet 访问。每个张量核有16个专用 SIMD 通道每个 octet 有8个通道每个 threadgroup 有 4 个通道。每个 threadgroup 通道将操作数送入内部缓冲区。 对于操作数矩阵 A 和 C每个 threadgroup 将操作数提取到其单独的缓冲区而对于操作数矩阵 B两个 threadgroup 都将操作数提取到共享缓冲区。操作模式和步骤决定了从中获取每个操作数的 threadgroup 通道。缓冲器为16个 FP16 FEDP 单元提供数据。在每个 FEDP 单元内部乘法在第一阶段并行执行累加发生在三个阶段总共四个流水线阶段。由于每个张量核由16个 FP16 FEDP 单元组成因此每个周期能够完成一个 4 × 4 4\times4 4×4 矩阵乘法。
参考资料
# [DOC] Where does cutlass’ detailed GEMM kernel? #526Dissecting the NVIDIA Volta GPU Architecture via MicrobenchmarkingModeling Deep Learning Accelerator Enabled GPUsNVIDIA Tensor Core微架构解析