什么是线程
一个线程包括程序代码,程序执行当前点,变量数值和数据结构。线程的执行是串行的。CUDA启动kernel后,启动大量线程,以充分利用数据的并行性。
CPU中的线程生成和调度需要上千的时钟周期,相比GPU只需要很少的时钟周期。更具体说,在一个Warp中的线程的切换几乎是没有开销的,因为线程的上下文直接存储在物理空间中。
线程是如何实现的
线程是啥,在上面说过了。程序的代码存储在主存中,寄存器PC记录程序执行点,寄存器IR存储当前需要执行的指令,寄存器和主存记录变量值和数据结构。
同CPU一样,GPU也提供上下文切换功能,多个线程以轮的方式共享处理单元,通过保存和恢复PC值,寄存器和存储器的内容,可以暂停一个线程的执行,并在稍后正确地恢复这个线程。
GPU的每个SM提供多个执行单元SP,他们共享一个PC和IR(存在与共享的控制单元中),如此以来同一时间,所有的线程执行形同的指令(这个指令就是IR中所存储内容)。
SIMD
SIMD
系统中,所有的并行处理单元在任何时候都执行相同的指令。因为是单指令
。
CUDA采用的是SPMD
,单程序多数据的执行形式,但是在一个SM内部其实是SIMD
执行warp中的所有线程,单指令多数据。这涉及到warp的工作原理。
warp与延时隐藏
一个Block中的线程被进一步分为32个为一个warp
。由于单指令
的定义,任何时刻一个warp中的所有线程只能取一条指令执行(IR中的指令)。在硬件结构中,每个SM有一个取指/分派
单元,由这个单元来向warp中的线程提供所要执行的指令。warp中每个线程的数据不同,但执行时间都相同。
一个SM中的使用线程数要多于SP数量,SM中硬件只能执行所有warp的一部分,这样做的目的是提高长延时操作的效率,达到延时隐藏的目的。具体说:当一个warp的一条指令需要等待一个长延时的操作时,这个warp将不会被SP选中执行,这个SP会去执行不需要等待的warp,从而达到隐藏等待时间的目的。所以当由足够多的warp时,硬件可以随时找到可悲执行的warp,如此变充分利用硬件资源。warp的被选择是零开销的。零开销的线程调度
。在warp的调度机制下,长延迟的操作被其他warp的指令执行隐藏,即延时隐藏
。
这也是为什么GPU不像CPU一样引入大量的缓存和分支预测,为了将更多的芯片面积作为浮点数的计算资源。
Warp中的线程访问Global memory时,做好的访问方式是coalesced access
即连续访问,如果不是连续访问,则会由于Cache miss
增加移动数据的开销。