据我所知,GPU在切换线程束(warp)以隐藏内存延迟。但我想知道,在什么条件下线程束会被切换出来?例如,如果一个线程束执行了一次加载操作,而数据已经在缓存中了,那么这个线程束会被切换出还是继续执行下一步计算?如果有两个连续的加法操作会发生什么呢?
首先,一旦一个线程块在一个多处理器(SM)上启动,所有它的warp都会停留直到它们全部退出kernel。因此,在启动一个块之前,需要有足够数量的寄存器供所有warp使用,并且需要有足够的空闲共享内存供整个块使用。
所以,warp从来不会被“切换出去”-传统意义上的warp间上下文切换是不存在的,其中上下文切换需要将寄存器保存到内存中并还原它们。
然而,SM会从所有驻留的warp中选择要发出的指令。事实上,SM更可能连续从不同warp中发出两条指令,而不是从同一个warp中发出,无论指令类型如何,无论存在多少ILP(指令级并行性)。不这样做会使SM面临依赖关系暂停。即使像加法这样的“快速”指令也具有非零延迟,因为算术管道需要多个周期。例如,在Fermi上,硬件可以每个周期发出2个或更多warp指令(峰值),并且算术管道延迟约为12个周期。因此,您需要多个warp处于运行状态,才能隐藏算术延迟,而不仅仅是内存延迟。
总的来说,warp调度的细节取决于架构,不公开文档化,并且几乎肯定会随着时间的推移而发生变化。CUDA编程模型与调度算法无关,您不应该在软件中依赖它。