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;