thread ID 的计算方式,简单来讲很像小学学的除法公式,本文转载自同窗一篇博客;并进行简单修改;ide
被除数 = 除数 * 商 + 余数线程
用公式表示:线程Id = blockId * blockSize + threadId博客
下面先理清几个关键点:it
grid 中 含有若干个 blocks,其中 blocks 的数量由 gridDim.x/y/z 来描述。某个 block 在此 grid 中的坐标由 blockIdx.x/y/z 描述。class
blocks 中含有若干个 threads,其中 threads 的数量由 blockDim.x/y/z 来描述。某个 thread 在此 block 中的坐标由 threadIdx.x/y/z 描述。thread
接着一个多维的坐标如何用一维数据表达呢?这里你们想想两位数和三位数,就是很好的例子。数字 = 百位数字 * 100 + 十位数字 * 10 + 个位数字。
当咱们得知每一个维度上的大小时,就能够利用这样的进制将三维坐标转换为1维坐标。
通常来讲坐标(x, y, z)分别所在的维度大小是(Dx, Dy, Dz),通常会把 z 当作高纬度,接着是 y ,最后是 x。grid
高维度坐标转一维坐标公式 id = Dx * Dy * z + Dx * y + x;坐标从0开始;维度从1开始;im
搞清楚了这些,咱们找几个例子开始计算:数据
Id = blockIdx.x * blockDim.x + threadIdx.x (公式1)di
blockSize = blockDim.x(一维 block 的大小)
blockId = Dx * Dy * z + Dx * y + x (三维 grid 中 block 的 id,用公式)
= gridDim.x * gridDim.y * blockIdx.z + gridDim.x * blockIdx.y + blockIdx.x
Id = (gridDim.x * gridDim.y * blockIdx.z + gridDim.x * blockIdx.y + blockIdx.x ) * blockDim.x + threadIdx.x
blockSize = blockDim.x * blockDim.y(二维 block 的大小)
blockId = blockIdx.x(一维 grid 中 block id)
threadId = Dx * y + x (二维 block 中 thread 的 id)
= blockDim.x * threadIdx.y + threadIdx.x
Id = blockIdx.x * (blockDim.x * blockDim.y) + blockDim.x * threadIdx.y + threadIdx.x
blockSize = blockDim.x * blockDim.y * blockDim.z(三维 block 的大小)
blockId = Dx * Dy * z + Dx * y + x(三维 grid 中 block 的 id,用公式)
= gridDim.x * gridDim.y * blockIdx.z + gridDim.x * blockIdx.y + blockIdx.x
threadId = Dx * Dy * z + Dx * y + x(三维 block 中 thread 的 id,用公式)
= blockDim.x * blockDim.y * threadIdx. z + blockDim.x * threadIdx.y + threadIdx.x
Thread ID = (gridDim.x * gridDim.y * blockIdx.z + gridDim.x * blockIdx.y + blockIdx.x) * (blockDim.x * blockDim.y * blockDim.z) + blockDim.x * blockDim.y * threadIdx. z + blockDim.x * threadIdx.y + threadIdx.x(公式2)
公式2为终极公式;坐标从0开始;维度从1开始;1D时,yz坐标为0,yz的维度为1,代入上式,便可得公式1;