如何为经线调度填充2D线程块?

时间:2013-02-23 19:30:06

标签: cuda

我理解对于具有31个线程的1D线程块,它将被填充到32个线程以进行warp执行。 具有31 * 31线程的2D块怎么样? warp scheduler会为每个维度填充额外的线程(即总共31个将被填充),或者这个2D块线程将被连接,只有最后一个线程将被填充(31 * 31 = 961; 961%32 = 1) ?

1 个答案:

答案 0 :(得分:9)

只有一个warp(最后一个)被填充。线程按x,y,z的顺序分组为warp。这样,如果你有一个奇怪的二维数组大小,比如17x17,它连续存储在内存中,你仍然可以从一个17x17线程块中创建32线程warp,这将产生合并的访问。这样,除最后一个之外,所有warp都将生成完全合并的访问。如果在整个过程中使用死线填充单个warp,则在此示例中,在内存访问方面会更浪费。

对于这个例子,至少,从机器利用率的角度来看,它的效果会更好。

对此的文档支持依赖于理解线程 ID 和线程索引不一样。

给定线程的线程索引由内置变量threadIdx.xthreadIdx.ythreadIdx.z标识。线程ID是唯一的(在线程块内),为每个线程分配的标量数。

线程ID和线程索引之间的关系由this statement

给出
  

“线程的索引及其线程ID以直接的方式相互关联:对于一维块,它们是相同的;对于二维块的大小(Dx,Dy),线程索引(x,y)的线程的ID是(x + y Dx);对于大小的三维块(Dx,Dy,Dz),索引(x,y,z)的线程的线程ID是(x + y Dx + z Dx Dy)。“

但将线程分组为warp已完成explicitly by thread ID

  

“块被分区为warp的方式总是相同的;每个warp包含连续的,增加的线程ID的线程,第一个warp包含线程0。”

因此,基于第一个语句,我们看到即使对于像17x17这样的奇数块形状,除了在线程块的维度内的线程之外,没有定义线程。然后根据第二个语句,按线程ID连续组合warp会创建warp,所有warp中都定义了线程(除了最后一个。)