Cuda块/网格尺寸:何时使用dim3?

use*_*792 7 cuda gpu

我需要对使用 dim3 设置 CUDA 内核中的线程数进行一些清理。

我有一个一维浮点数组中的图像,我正在将其复制到设备中:

checkCudaErrors(cudaMemcpy( img_d, img.data, img.row * img.col * sizeof(float), cudaMemcpyHostToDevice));
Run Code Online (Sandbox Code Playgroud)

现在我需要设置网格和块大小来启动我的内核:

dim3 blockDims(512);
dim3 gridDims((unsigned int) ceil(img.row * img.col * 3 / blockDims.x));
myKernel<<< gridDims, blockDims>>>(...)
Run Code Online (Sandbox Code Playgroud)

我想知道:在这种情况下,由于数据是一维的,如果我使用一个 dim3 结构有关系吗?使用的任何好处

unsigned int num_blocks = ceil(img.row * img.col * 3 / blockDims.x));
myKernel<<<num_blocks, 512>>>(...)
Run Code Online (Sandbox Code Playgroud)

反而?

另外,我的理解是否正确,在使用 dim3 时,我将在内核中引用带有 2 个索引的线程 ID:

int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
Run Code Online (Sandbox Code Playgroud)

当我不使用dim3 时,我只会使用一个索引?

非常感谢,

pQB*_*pQB 5

您在内存中排列数据的方式与您将如何配置内核线程无关。

内存总是一维连续的字节空间。但是,访问模式取决于您如何解释数据以及您如何通过 1D、2D 和 3D 线程块访问它们。

dim3 是基于 uint3 的整数向量类型,用于指定维度。定义类型为 dim3 的变量时,任何未指定的组件都将初始化为 1。

块和网格也是如此。

阅读更多信息:http : //docs.nvidia.com/cuda/cuda-c-programming-guide/#dim3

因此,在这两种情况下:dim3 blockDims(512);myKernel<<<num_blocks, 512>>>(...)你将永远有机会获得threadIdx.y和threadIdx.z。

由于线程 ID 从零开始,您还可以使用y维度将内存位置计算为行主顺序:

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

int gid = img.col * y + x; 
Run Code Online (Sandbox Code Playgroud)

因为blockIdx.y并且threadIdx.y将为零。

总而言之,如果您使用dim3结构,这很重要。我很清楚线程的配置在哪里定义,1D、2D 和 3D 访问模式取决于您如何解释数据以及您如何通过 1D、2D 和 3D 线程块访问它们。