Introduction
本文内容主要系摘录翻译自Ang Li博士的毕业论文。
1. GPU历史
Arch. | Release Year | Compute Capability | Process | Most highlighted Features | Flagship GTX/Tesla/Jetson GPUs |
---|---|---|---|---|---|
Tesla | 2008 | 1.0, 1.1, 1.2, 1.3 | 65 nm | GPU baseline architecture | GTX8800, GTX9800, GTX280,Tesla1060 |
Fermi | 2010 | 2.0, 2.1 | 40 nm | L1/L2 caches, dual scheduler | GTX480, GTX460, GTX580,Tesla2070 |
Kepler | 2012 | 3.0, 3.2, 3.5, 3.7 | 40/28 nm | Floating-point performance | GTX680, GTX-TitanZ, Tesla-K10,Tesla-K20, Tesla-K40, Tesla-K80,Jetson-TK1 |
Maxwell | 2014 | 5.0, 5.2, 5.3 | 28 nm | Power efficiency | GTX750Ti, GTX980, GTX-TitanX,Tesla-M40, Tesla-M60, Jetson-TX1 |
Pascal | 2016 | 6.0 | 16 nm | 3D Memory, numeric SMs | Tesla-GP100, GTX1080 |
架构变化
1.1 几种架构特性简述
Fermi第一次出现了两级cache的设计。
Kelper有巨大的计算能力,因为它们每个SM有最多的CUDA cores。
从Maxwell开始注重功耗。
Pascal则因为其3D的memory架构拥有了快速的half-percision(16 bits)的计算。
GTX是桌面发型版,Telsa面向HPC,Jetson则是嵌入式设备。
2. GPU
GPU由多个streaming-multiprocessors (SMs)组成,它们通过crossbar内部互联网络共享L2 Cache和DRAM控制器。一个SM包含多个scalar processor cores (SPs) 和两种其他类型的功能单元(the Double-Precision Units (DPUs) for double-precision (DP) floating-point calculations and the Special-Function Units (SFUs) for processing transcendental functions and texture-fetching interpolations),还包含register files (RFs), load- store units (LSUs), scratchpad memory (i.e., shared memory), and various caches (i.e., instruction cache, constant cache, texture/read-only cache, L1 cache) for on-chip data caching。
2.1 功能单元
Scalar-Processor (SP): SM的主要基础处理器,实现基本的整数、浮点数计算,比较和类型转换等操作。每个SP包含一个单精度浮点数处理单元FPU和一个整数算数/逻辑单元ALU。都是流水线的。
Special-Function-Unit (SFU): SFU实现了快速透明的函数计算(sin,cos等)和平面属性插值。
Double-Precision-Unit (DPU): 专门的双精度计算单元。
Load-Store-Unit (LSU): 从内存读写数据的单元。包含独立的计算单元来快速计算内存请求的来源和目的地址。
2.1.2 设备内存
Memory | On/Off Chip | Cached | Access | Scope | Lifetime |
---|---|---|---|---|---|
Register Files | On | N/A | Read/Write | Per-thread | Thread |
Local Memory | Off | L1/L2 | Read/Write | Per-thread | Thread |
Shared Memory | On | N/A | Read/Write | Thread Block (CTA) | Thread Block (CTA) |
Global Memory | Off | L1/L2 | Read/Write | GPU+CPU | Host Allocation |
Constant Memory | Off | Constant cache | Read Only | GPU+CPU | Host Allocation |
Texture Memory | Off | Texture cache | Read Only | GPU+CPU | Host Allocation |
Register Files (RF): GPU的寄存器很大,出于吞吐量的考虑,划分成banks。因此相比于CPU寄存器,GPU寄存器的latency更大,而且有更多潜在的bank conflicts。
Local Memory (LM): local memory不是物理空间,而是global memory的一部分。它是线程私有的,主要用来临时的spilling,比如寄存器溢出,或者数组在Kernel里声明了,但编译器无法获得他准确的indexing。Local memory在Fremi和Kepler中可以被L1和L2 cached,但是在Maxwell和Pascal中只能被L2 cached。寄存器溢出到local memory会造成巨大的性能下降(引起了更多的指令和内存拥挤)尤其是cache miss时。
Shared Memory (HM,SMEM): 又称为scratchpad memory,是片上的存储,SM里的所有单元共享。它可以用来作为同一个thread blocks里不同线程之间快速数据交换的通讯接口。由于是片上存储,带宽很大,访问延迟很小。因此,把global/local memory的访问迁移到SMEM上的优化是被编程手册推荐的。为了获得更高的带宽,SMEM被划分成banks,这样就可以并行的访问(寄存器文件和L2 cache也类似)。但是如果在一次内存请求中,访问的两个地址落在了同一个bank,就造成了bank conflict,此时请求需要串行化,从而降低了SMEM的性能。
Global Memory (GM): 又称device memory,GPU片下内存,GPU主存。它是GPU性能的主要瓶颈。GM可达到的吞吐量取决于:(1)GM物理带宽限制,即pin数、线长度和DRAM的物理特性。因此在kelper以前增长缓慢,但是Pascal使用了3D栈内存技术,性能获得了巨大提升。(2) 访存请求合并。LSU一开始会计算每个warp的目标地址。在memory fetch之前,有一个特殊的地址合并硬件来检查同一个warp里地址是否是连续分布的。
Constant Memory (CM) / Constant Cache: 常量内存用来存储在Kernel执行期间没有改变的数据。在所有GPU上都是64KB的off-chip。和local memory类似,都是Global memory的一部分。不被L1或L2 cached,有专门的constant cache。每个SM上8/10KB的常量cache被专门设计,以便 the data of a single memory address can be broadcast to all threads across the warp at a time。
Texture Memory (TM) / Texture Cache: 又称surface memory也在全局内存上。被texture cache cached。Texture cache针对2D的空间局部性进行了优化。
2.1.3 设备缓存
L1 Data-Cache:在Fermi上首次被提出来。SM的私有L1 Cache和SMEM共享片上存储,他们的大小是可以配置的,Fermi上16/48 or 48/16,Kepler上32/32 or 48/16。L1 cache line是128B。L1 data cache缓存global memory读和local memory的读写,并且是non-corherent。local memory主要用来寄存器溢出、函数调用和自动变量。当L1 cache 被用来缓存global memory时是只读的,当被用来缓存local memory时也是可写的。从Maxwell开始,传统的L1 cache被统一到了Texture cache里。
L2 Cache: 它被用来缓存各种类型的memory access,且和宿主机的CPU memory保持一致性(?)。采取写回策略。
2.1.4 NC and ROP
Interconnection Network (NC): crossbar network.它允许多个SM和L2 banks之间同时通信。crossbar NC包含一条地址线和两条数据线。地址线是单向的,从SM到L2 banks,而两条数据线则是双向的,存储SM和L2 banks。因此,通讯是点到点的。一个内存请求队列(memory-request queue, MRQ)和一个bank 加载队列( bank load queue, BLQ)分别对应了一个SM和L2 bank。当load请求从SM中的LSU产生时,它会首先缓存在MRQ里,然后通过NC被分发到目的BLQ中。在BLQ中等待一会,然后这个请求将被L2 banks处理。crossbar network在同时多个连接时有很高的切换代价,特别是当访问请求随机且数据量大。
Raster Operation Processor (ROP)。
2.2 GPU执行模型 - 大批量SMIT和线程映射
Arch. | CC. | Representative GPU | SMs | RF | SP | SFU | DPU | LSU | Shared Mem | Const | Texture | L1 | L2 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Tesla | 1.0 | Tesla-C870 | 8 | 8 KB | 8 | 2 | N/A | N/A | 16 KB | 8 KB | 12 KB | N/A | N/A |
Tesla | 1.3 | Tesla-C1060 | 10 | 16 KB | 8 | 2 | N/A | N/A | 16 KB | 8 KB | 12 KB | N/A | N/A |
Fermi | 2.0 | Tesla-C2070 | 16 | 32 KB | 32 | 4 | 16 | 16 | 16/48 KB | 8 KB | 12 KB | 48/16 KB | 768 KB |
Fermi | 2.1 | GTX-460 | 16 | 32 KB | 48 | 8 | 4 | 16 | 16/48 KB | 8 KB | 12 KB | 48/16 KB | 512 KB |
Kepler | 3.0 | Tesla-K10 | 8 | 64 KB | 192 | 32 | 8 | 32 | 16/32/48 KB | 8 KB | 48 KB | 48/32/16 KB | 512 KB |
Kepler | 3.5 | Tesla-K40 | 15 | 64 KB | 192 | 32 | 64 | 32 | 16/32/48 KB | 8 KB | 48 KB | 48/32/16 KB | 1536 KB |
Kepler | 3.7 | Tesla-K80(x2) | 13x2 | 128 KB | 192 | 32 | 64 | 32 | 112 KB | 8 KB | 48 KB | 16 KB | 1536 KB |
Maxwell | 5.0 | GTX-750Ti | 5 | 64 KB | 128 | 32 | 4 | 32 | 64 KB | 10 KB | 24 KB | N/A | 2048 KB |
Maxwell | 5.2 | Tesla-M40 | 24 | 64 KB | 128 | 32 | 4 | 32 | 96 KB | 10 KB | 48 KB | N/A | 2048 KB |
Pascal | 6.0 | Tesla-P100 | 60 | 64 KB | 64 | 16 | 32 | 16 | 64 KB | 10 KB | 48 KB | N/A | 4096 KB |
2.2.1 SIMT
single-instruction-multiple-threads,SIMT,单指令多线程。
thread blocks or Cooperative-Thread-Arrays (CTAs)
一个Kernel函数包含很多同时运行的轻量级GPU线程,而这些线程被划分成多个thread blocks组。当Kernel开始运行时,CTAs被分配到不同的SM上去,也可能其中几个CTA被分配到相同的SM上去。
CTA里面的threads则进一步分组管理,这些分组叫warp,warp内遵循lockstep规则,即所有线程同步执行。在SM里,warp是基本的调度、执行和读写cache/memory的单元。
如果一个warp里的线程在某个点(if-else等)出现了分歧(warp divergence),则所有的分支顺序执行。执行if的时候,else的线程被挂起。在分歧(if-else)结束以后,再继续lockstep的执行。warp divergence造成了巨大的overhead。
GPU支持multi-issuing和multi-dispatching。在执行期间,dual- or quad- warp scheduler选择两个或四个ready状态的warps分调度到不同的功能单元上(SPs,SFUs,当然大多数指令都是在SP上完成的)。
2.2.2 线程级别的映射
- 线程以warp为单位被映射到SP、SFU或者DPU上。
- CTA被映射到SM上。
- grid映射到GPU device。
2.3 GPU编程模型
2.3.1 Kernel配置
Arch. | CC. | Grids/GPU | CTAs/Grid | Thds/CTA | CTAs/SM | Thds/SM | Thds/Warp | Warps/CTA | Warps/SM |
---|---|---|---|---|---|---|---|---|---|
Tesla | 1.0 | 1 | (512,512,64) | 512 | 8 | 768 | 32 | 16 | 24 |
Tesla | 1.1 | 1 | (512,512,64) | 512 | 8 | 768 | 32 | 16 | 24 |
Tesla | 1.2 | 1 | (512,512,64) | 512 | 8 | 1024 | 32 | 16 | 32 |
Tesla | 1.3 | 1 | (512,512,64) | 512 | 8 | 1024 | 32 | 16 | 32 |
Fermi | 2.0 | 16 | ($2^{16}$,$2^{16}$,$2^{16}$) | 1024 | 8 | 1536 | 32 | 32 | 48 |
Fermi | 2.1 | 16 | ($2^{16}$,$2^{16}$,$2^{16}$) | 1024 | 8 | 1536 | 32 | 32 | 48 |
Kepler | 3.0 | 16 | ($2^{32}-1$,$2^{16}$,$2^{16}$) | 1024 | 16 | 2048 | 32 | 32 | 64 |
Kepler | 3.2 | 4 | ($2^{32}-1$,$2^{16}$,$2^{16}$) | 1024 | 16 | 2048 | 32 | 32 | 64 |
Kepler | 3.5 | 32 | ($2^{32}-1$,$2^{16}$,$2^{16}$) | 1024 | 16 | 2048 | 32 | 32 | 64 |
Kepler | 3.7 | 32 | ($2^{32}-1$,$2^{16}$,$2^{16}$) | 1024 | 16 | 2048 | 32 | 32 | 64 |
Maxwell | 5.3 | 32 | ($2^{32}-1$,$2^{16}$,$2^{16}$) | 1024 | 32 | 2048 | 32 | 32 | 64 |
Maxwell | 5.2 | 32 | ($2^{32}-1$,$2^{16}$,$2^{16}$) | 1024 | 32 | 2048 | 32 | 32 | 64 |
Maxwell | 5.3 | 16 | ($2^{32}-1$,$2^{16}$,$2^{16}$) | 1024 | 32 | 2048 | 32 | 32 | 64 |
Pascal | 6.0 | 32 | ($2^{32}-1$,$2^{16}$,$2^{16}$) | 1024 | 32 | 2048 | 32 | 32 | 64 |
2.3.2 编译
PTX stands for Parallel-Thread-Execution,是一个中间级的汇编代码。而cubin二进制则已经指定了架构。
Shader-Assembly (SASS),真正的机器汇编,由cubin文件经过cuobjdump工具转换而来。目前没有官方的sass to cubin的工具。
2.4 GPU评测模型
2.4.1 模拟器
略
2.4.2 Benchmarks
2.4.3 Profiling-Tools
Visual Profiler, Command-line Profiler and nvprof. intensively utilized for measuring different runtime events and performance metrics, such as kernel execution time, L1 hit rate, etc. Please refer to [122] for the details about the profiler tools.
Reference
[mathjax]
Comments