题
如何被组织的线程由GPU执行?
解决方案
硬件
如果一个GPU设备有,例如,4个多台,它们可以运行每个768个线程:那么在给定时刻不超过4×768线程将并行真正运行(如果你计划在更多的线程,他们将会等待轮到他们)。
软件
线程块被组织。 A嵌段是由多处理单元执行。 块的线程可以被中鉴定(索引),使用1Dimension(x)中,2Dimensions(X,Y)或3Dim索引(X,Y,Z),但在任何情况下,x ýž<= 768对我们的例子(其它限制适用于X,Y,Z,看到导向件和设备能力)。
显然,如果你需要更多的比那些4个* 768线程,你需要超过4个街区。 块可被编入索引也1D,2D或3D。有等待进入块的队列 该GPU(因为,在我们的例子中,GPU有4个多处理器,只有4块 被同时执行)。
现在简单的情况下:处理512×512的图像
假设我们要一个线程来处理一个像素(i,j)的
我们可以使用的每64个线程块。然后我们需要512 *六十四分之五百一十二= 4096块 (因此具有512×512的线程= 4096 * 64)
这是常见的组织(以使索引图像更容易)在具有blockDim = 8×8(64级每个块的线程)2D块的线程。我更喜欢称它为threadsPerBlock。
dim3 threadsPerBlock(8, 8); // 64 threads
和2D gridDim = 64×64个块(4096块所需要的)。我更喜欢称它为numBlocks。
dim3 numBlocks(imageWidth/threadsPerBlock.x, /* for instance 512/8 = 64*/
imageHeight/threadsPerBlock.y);
内核启动是这样的:
myKernel <<<numBlocks,threadsPerBlock>>>( /* params for the kernel function */ );
最后:将有像被分配,其中块是等待“的4096个块队列” GPU的多处理器获取其64个线程执行的一个
在内核中的像素(i,j)至由一个线程处理的计算是这样的:
uint i = (blockIdx.x * blockDim.x) + threadIdx.x;
uint j = (blockIdx.y * blockDim.y) + threadIdx.y;
其他提示
假设一个9800GT GPU: 14个多处理机,每个都具有8个threadprocessors和warpsize是32,这意味着每个threadprocessor处理多达32个线程。 14 * 8 * 32 = 3584是实际工作cuncurrent线程的最大数目。
如果你有超过3584个线程执行这个内核(说4000个线程,你如何定义块和电网这并不重要GPU将像对待一样。):
func1();
__syncthreads();
func2();
__syncthreads();
然后是这两个功能的执行的顺序如下:
1.func1对于第一线程3584执行
2.func2对于第一线程3584执行
3.func1针对剩余线程
执行4.func2针对剩余线程
执行