thread ID 的計算方式,簡單來說很像小學學的除法公式,本文轉載自同學一篇博客;並進行簡單修改;
被除數 = 除數 * 商 + 余數
用公式表示:線程Id = blockId * blockSize + threadId
- blockId :當前 block 在 grid 中的坐標(可能是1維到3維)
- blockSize :block 的大小,描述其中含有多少個 thread
- threadId :當前 thread 在 block 中的坐標(同樣從1維到3維)
下面先理清幾個關鍵點:
grid 中 含有若干個 blocks,其中 blocks 的數量由 gridDim.x/y/z 來描述。某個 block 在此 grid 中的坐標由 blockIdx.x/y/z 描述。
blocks 中含有若干個 threads,其中 threads 的數量由 blockDim.x/y/z 來描述。某個 thread 在此 block 中的坐標由 threadIdx.x/y/z 描述。
接着一個多維的坐標如何用一維數據表達呢?這里大家想一想兩位數和三位數,就是很好的例子。數字 = 百位數字 * 100 + 十位數字 * 10 + 個位數字。
當我們得知每個維度上的大小時,就可以利用這樣的進制將三維坐標轉換為1維坐標。
一般來說坐標(x, y, z)分別所在的維度大小是(Dx, Dy, Dz),一般會把 z 看成高緯度,接着是 y ,最后是 x。
高維度坐標轉一維坐標公式 id = Dx * Dy * z + Dx * y + x;坐標從0開始;維度從1開始;
搞清楚了這些,我們找幾個例子開始計算:
1D grid, 1D block
- blockSize = blockDim.x
- blockId = blockIdx.x
- threadId = threadIdx.x
Id = blockIdx.x * blockDim.x + threadIdx.x (公式1)
3D grid, 1D block
-
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
- threadId = threadIdx.x (一維 block 中 thread 的 id)
Id = (gridDim.x * gridDim.y * blockIdx.z + gridDim.x * blockIdx.y + blockIdx.x ) * blockDim.x + threadIdx.x
1D grid, 2D block
-
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
3D grid, 3D block
-
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;
參考鏈接:https://www.cnblogs.com/imagineincredible/p/12455776.html