GPU线程编号规则及指定配置下线程坐标计算正确性验证
CUDA网格、块与线程编号及坐标计算解答
你声明的线程与块配置如下:
dim3 threads_per_block(2,2,2); dim3 blocks_per_grid(2,2,2); MyKernel<<<blocks_per_grid, threads_per_block>>>(... ... ...);
一、网格中块与线程的编号规则
网格中块与线程的标准编号遵循CUDA的维度遍历逻辑:
- 块(block)的编号:
2×2×2的块网格中,blockIdx.x/blockIdx.y/blockIdx.z的取值范围均为[0,1]。遍历顺序为x维度优先变化,其次y维度,最后z维度,块的全局顺序依次是:(0,0,0)→(1,0,0)→(0,1,0)→(1,1,0)→(0,0,1)→(1,0,1)→(0,1,1)→(1,1,1)。 - 线程(thread)的编号:
每个2×2×2的线程块中,threadIdx.x/threadIdx.y/threadIdx.z的取值范围均为[0,1]。块内遍历顺序同样是x维度优先变化,其次y维度,最后z维度,块内线程顺序依次是:(0,0,0)→(1,0,0)→(0,1,0)→(1,1,0)→(0,0,1)→(1,0,1)→(0,1,1)→(1,1,1)。
若你提供的图不符合上述顺序,即为错误,正确编号以上述规则为准。
二、线程#36的坐标计算正误判断
你给出的计算逻辑错误,正确计算过程如下:
- 总线程数:
(2×2×2)块 × (2×2×2)线程/块 = 64,线程编号范围为0~63。 - 定位线程#36:
- 每个块含8个线程,所在块的全局索引为
36 // 8 = 4(从0开始计数) - 块内线程索引为
36 % 8 = 4
- 每个块含8个线程,所在块的全局索引为
- 计算
blockIdx:int blockIdx_x = 4 % gridDim.x = 4 % 2 = 0; int blockIdx_y = (4 / gridDim.x) % gridDim.y = (4/2) % 2 = 0; int blockIdx_z = 4 / (gridDim.x * gridDim.y) = 4 / (2*2) = 1; - 计算
threadIdx:int threadIdx_x = 4 % blockDim.x = 4 % 2 = 0; int threadIdx_y = (4 / blockDim.x) % blockDim.y = (4/2) % 2 = 0; int threadIdx_z = 4 / (blockDim.x * blockDim.y) = 4 / (2*2) = 1; - 最终线程坐标:
int x = blockIdx_x * blockDim.x + threadIdx_x = 0*2 + 0 = 0; int y = blockIdx_y * blockDim.y + threadIdx_y = 0*2 + 0 = 0; int z = blockIdx_z * blockDim.z + threadIdx_z = 1*2 + 1 = 3;
内容的提问来源于stack exchange,提问作者user366312
相关产品推荐
相关产品推荐

