我有一个由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,....提前感谢....
答案 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数据的维度为xDim
,yDim
和zDim
,则可以按如下方式形成一个通用的线程块网格:
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;
上述方法将创建等于或大于总数据大小的线程总数。额外的线程可能会导致无效的内存访问。因此,在内核中执行绑定检查。您可以通过将xDim
,yDim
和zDim
作为内核参数并在内核中添加以下行来执行此操作:
if(x>=xDim || y>=yDim || z>=zDim) return;