我是CUDA的初学者,我的同事总是使用以下包装来设计内核:
__global__ void myKernel(int nbThreads)
{
int threadId = blockDim.x*blockIdx.y*gridDim.x //rows preceeding current row in grid
+ blockDim.x*blockIdx.x //blocks preceeding current block
+ threadIdx.x;
if (threadId < nbThreads)
{
statement();
statement();
statement();
}
}
他们认为在某些情况下,CUDA可能会启动比指定对齐/变形更多的线程,因此我们需要每次检查它。 但是,到目前为止,我还没有看到互联网上的示例内核实际进行此验证。
CUDA实际上可以启动比指定的块/网格尺寸更多的线程吗?
答案 0 :(得分:4)
CUDA不会启动比块/网格尺寸指定的更多的线程。
然而,由于块尺寸的粒度(例如,希望块尺寸为32的倍数,并且其尺寸限制为1024或512),通常情况下它是难以匹配线程网格在数值上等于所需的问题大小。
在这些情况下,典型的行为是启动更多线程,根据块粒度有效地舍入到下一个偶数大小,并使用&#34;线程检查&#34;内核中的代码,以确保&#34;额外的线程&#34;,即那些超出问题规模的线程,不做任何事情。
在您的示例中,可以通过编写以下内容来澄清:
__global__ void myKernel(int problem_size)
if (threadId < problem_size)
传达预期的内容,只有与问题大小相对应的线程(可能与启动的网格大小不匹配)才能进行任何实际工作。
作为一个非常简单的例子,假设我想在长度为10000个元素的向量上进行向量加法。 10000不是32的倍数,也不是小于1024,所以在典型的实现中,我会启动多个线程块来完成工作。
如果我希望每个threadblock都是32的倍数,那么我可以选择的线程块数量不会超过10000个线程。因此,我可能会在一个threadblock中选择256个线程,并启动40个线程块,总共给出10240个线程。使用线程检查,我防止&#34;额外&#34;做任何事情的240个线程。