我有一个由 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,....提前谢谢....
我有一个由 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,....提前谢谢....
单个线程索引(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 设备都不支持。目前,计算能力 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;