在CUDA_C_Programming_Guide,第2章,线程层次结构
中
__global__ void MatAdd(float A[N][N],float B[N][N],float C[N][N])
{
int i=blockId.x*blockDim.x+threadIdx.x;
int j=blockId.y*blockDim.y+threadIdx.y;
if(i<N&&j<N)
C[i][j]=A[i][j]+B[i][j];
}
int main()
{
....
dim3 threadPerBlock(16,16);
dim3 numBlock(N/threadPerBlcok.x,N/threadPerBlock.y);
MatAdd<<<numBlocks,threadPerBlock>>>(A,B,C);
....
}
我是个新人,无法理解“int i = blockIdx.x * blockDim.x + threadIdx.x”。为什么会这样? 有没有人可以向我解释一下? 非常感谢。 例如,如何使用“i”和“j”确认块(1,1)中的线程(1,1)?
答案 0 :(得分:1)
我在&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; CUDA编程:使用GPU进行并行计算的开发人员指南&gt; autor:Shane Cook。
在第5章中,有一个明确的解释。
至于2D数组,我们需要dim3来创建2D布局线程。
“dim3 threadPerBlock(16,16)
”表示单个块的x轴有16个螺纹,Y轴有16个螺纹。
“dim3 numBlocks(N/threadPerBlock.x,N/threadPerBlock.y)
”表示单个网格沿x轴具有N / threadPerBlock.x块,沿y轴具有N / threadPerBlock.y。
gridDim.x
或gridDim.y
表示网格中沿x / y轴的块数。
blockDim.x
或blockDim.y
表示块中x / y轴上的线程数。
threadIdx.x
或threadIdx.y
表示块中x / u轴的线程索引。
blockIdx.x
或block.idx.y
表示网格中沿x / y轴的块索引。
所以如果我们想要知道绝对线程索引,我们应该知道当前块后面有多少块以及当前线程后面有多少线程(row *(sizeof(array_element)* width)))+((sizeof(array_element)* offset) )。所以我们得到i= blockIdx.x*blockDim.x+threadIdx.x
。
有图片显示网格,块和线程尺寸。
enter image description here