根据我对NVIDIA的CUDA架构的理解,线程的执行发生在~32的组中,称为“warp”。一次安排多个warp,并从任何warp发出指令(取决于某些内部算法)。
现在,如果我在设备上说16KB的共享内存,并且每个线程使用400字节的共享内存,那么一个warp将需要400 * 32 = 12.8 KB。这是否意味着GPU一次不能实际调度多于1个warp,无论我在给定块中启动多少个线程?
答案 0 :(得分:3)
从资源的角度来看(寄存器,共享内存等),重要的单位是 threadblock ,而不是warp。
为了安排执行线程块,SM上必须有足够的空闲资源来满足整个线程块的需要。网格中的所有线程块都具有完全相同的资源要求。
如果SM当前没有执行线程块(例如在内核启动时),则SM应该至少具有足够的资源来满足单个线程块的需要。如果不是这样,内核启动将失败。例如,如果每个线程的寄存器数乘以每个块的线程数超过SM中的寄存器数,就会发生这种情况。
在SM调度单个线程块之后,可以根据可用资源调度其他线程块。因此,为了扩展寄存器类比,如果每个线程块需要30K寄存器(regs / thread * threads / block),并且SM具有最大64K寄存器,那么最多可以调度两个线程块(即它们的warp可能被带入由SM执行。
通过这种方式,任何可能被执行的warp都已经为它分配了足够的资源。这是调度机制的主要部分,它允许SM将执行从一个warp切换到另一个war,而没有延迟(快速上下文切换)。