目录
一、初步认识
二、Fermi架构
三、Kepler 架构
3.1 动态并行
3.2 Hyper-Q
一、初步认识
SM(Streaming Multiprocessors)是GPU架构中非常重要的部分,GPU硬件的并行性就是由SM决定的。以Fermi架构为例,其包含以下主要组成部分:
- CUDA cores
- Shared Memory / L1Cache
- Register File
- Load / Store Units
- Special Function Units
- Warp Scheduler
GPU中每个SM都设计成支持数以百计的线程并行执行,并且每个GPU都包含了很多的SM,所以GPU支持成百上千的线程并行执行。当一个kernel启动后,thread会被分配到这些SM中执行。大量的thread可能会被分配到不同的SM,但是同一个block中的thread必然在同一个SM中并行执行
CUDA采用 Single Instruction Multiple Thread(SIMT,单指令多线程)的架构来管理和执行thread,thread以32个为单位组成一个单元,称作warp。warp中所有线程并行的执行相同的指令。每个thread拥有独立的 指令地址计数器 和 状态寄存器,并且用该线程自己的数据执行指令
SIMT和SIMD(Single Instruction Multiple Data,单指令多数据)类似,SIMT应该算是SIMD的升级版,更灵活,但效率略低,SIMT是NVIDIA提出的GPU新概念。二者都通过将同样的指令广播给多个执行官单元来实现并行。一个主要的不同就是,SIMD要求所有的 vector element 在一个统一的同步组里同步的执行,而SIMT允许线程们在一个warp中独立的执行。SIMT有三个SIMD没有的主要特征:
- 每个thread拥有独立的指令地址计数器
- 每个thread拥有独立的状态寄存器
- 每个thread可以有独立的执行路径
一个 block 只会由一个 SM 调度,block 一旦被分配好 SM,该 block 就会一直驻留在该 SM 中,直到执行结束。一个 SM 可以同时拥有多个 block
大部分 thread 只是逻辑上并行,并不是所有的 thread 可以在物理上同时执行。这就导致,同一个 block 中的线程可能会有不同步调
并行 thread 之间的共享数据会导致竞态:多个线程请求同一个数据会导致未定义行为。CUDA 提供了 API 来同步同一个 block 的 thread 以保证在进行下一步处理之前,所有 thread 都到达某个时间点。不过,没有提供什么原子操作来保证 block 之间的同步的
同一个 warp 中的 thread 可以以任意顺序执行,active warps 被 SM 资源限制。当一个 warp 等待时,SM 就可以调度驻留在该 SM 中另一个可用 warp。在并发的 warp 之间切换是没什么消耗的,因为硬件资源早就被分配到所有 thread 和 block,所以该新调度的 warp 的状态已存储在 SM 中了
SM可以看做GPU的心脏,寄存器和共享内存是SM的稀缺资源。CUDA将这些资源分配给所有驻留在SM中的thread。这些有限的资源就使每个 SM 中 active warps 有非常严格的限制,也就限制了并行能力。所以,掌握部分硬件知识,有助于CUDA性能提升
二、Fermi架构
Fermi是第一个完整的GPU计算架构
- 512个 accelerator cores 即所谓 CUDA cores(包含ALU和FPU)
- 16个 SM,每个 SM 包含32个 CUDA core
- 六个384位 GDDR5 DRAM,支持 6GB global on-board memory
- GigaThread engine 将 thread blocks 分配给 SM 调度
- 768KB L2 cache
- 每个 SM 有 16 个 load/store 单元,允许每个 clock cycle 为 16 个 thread(即所谓 half-warp)计算源地址和目的地址
- Special function units(SFU)用来执行 sin cosine 等(一种特殊的硬件单元,主要用于高效地执行特定的数学函数计算)
- 每个 SM 两个 warp scheduler 两个 instruction dispatch unit,当一个 block 被分配到一个 SM 中后,所有该 block 中的 thread 会被分到不同的 warp 中
- Fermi(compute capability 2.x)每个 SM 同时可处理 48 个 warp 共计1536个 thread
每个SM由以下几部分组成:
- 执行单元(CUDA cores)
- 调度分配 warp 的单元
- shared memory,register file,L1 cache
三、Kepler 架构
Kepler相较于Fermi更快,效率更高,性能更好
- 15个 SM
- 6个 64位 memory controller
- 192 个单精度 CUDA cores,64 个双精度单元,32 个 SFU,32 个 load/store 单元(LD/ST)
- 增加 register file 到 64K
- 每个 Kepler 的 SM 包含四个 warp scheduler、八个 instruction dispatchers,使得每个 SM 可以同时 issue 和执行四个 warp
- Kepler K20X(compute capability 3.5)每个 SM 可以同时调度64个 warp 共计 2048 个thread
3.1 动态并行
Dynamic Parallelism 是 Kepler 的新特性,允许 GPU 动态的启动新的 Grid。有了这个特性,任何 kernel 内都可以启动其它的 kernel。这样直接实现了kernel的递归以及解决了kernel之间数据的依赖问题
3.2 Hyper-Q
Hyper-Q是Kepler的另一个新特性,增加了CPU和GPU之间硬件上的联系,使CPU可以在GPU上同时运行更多的任务。增加GPU的利用率减少CPU的闲置时间。Fermi依赖一个单独的硬件上的工作队列来从CPU传递任务给GPU,这样在某个任务阻塞时,会导致之后的任务无法得到处理,Hyper-Q解决了这个问题。相应的,Kepler为GPU和CPU提供了32个工作队列