如何计算3D网格中的各个线程坐标索引?

时间:2013-07-19 16:52:04

标签: cuda

我有一个由3D块组成的3D网格。我希望每次调用内核时计算每个坐标的各个线程索引。我有这些参数:

dim3 blocks_query(32,32,32);
dim3 threads_query(32,32,32);
kernel<<< blocks_query,threads_query >>>();

在内核中,我希望计算x,y和z坐标的各个值,例如,x = 0,y = 0,z = 0,x = 0,y = 0,z = 1,x = 0,y = 0,z = 2,....提前感谢....

1 个答案:

答案 0 :(得分:1)

可以在内核中计算单个线程索引(x,y,z坐标),如下所示:

int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
int z = blockIdx.z * blockDim.z + threadIdx.z;

请记住,每个块的线程数受GPU限制。因此,您创建的块大小无效。

dim3 threads_query(32,32,32)

它等于每块32768个线程,这是任何当前CUDA设备都不支持的。目前,Compute功能2.0及更高版本的GPU支持每块最多1024个线程,而旧GPU最多支持512个线程。您应该减小块大小,否则内核将无法启动。 另外需要注意的是,您正在创建仅在Compute 2.0及更高版本的CUDA GPU上支持的3D网格。

<强>更新

假设您的3D数据的维度为xDimyDimzDim,则可以按如下方式形成一个通用的线程块网格:

dim3 threads_query(8,8,8);

dim3 blocks_query;

blocks_query.x = (xDim + threads_query.x - 1)/threads_query.x;
blocks_query.y = (yDim + threads_query.y - 1)/threads_query.y;
blocks_query.z = (zDim + threads_query.z - 1)/threads_query.z;

上述方法将创建等于或大于总数据大小的线程总数。额外的线程可能会导致无效的内存访问。因此,在内核中执行绑定检查。您可以通过将xDimyDimzDim作为内核参数并在内核中添加以下行来执行此操作:

if(x>=xDim || y>=yDim || z>=zDim) return;