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

时间:2015-06-30 14:47:44

标签: cuda gpu

关于使用dim3来设置我的CUDA内核中的线程数,我需要一些清理。

我在1D浮点数组中有一个图像,我正在使用它复制到设备

checkCudaErrors(cudaMemcpy( img_d, img.data, img.row * img.col * sizeof(float), cudaMemcpyHostToDevice));

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

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

我想知道:在这种情况下,由于数据是1D,如果我使用dim3结构是否重要?使用

的任何好处
unsigned int num_blocks = ceil(img.row * img.col * 3 / blockDims.x));
myKernel<<<num_blocks, 512>>>(...)

代替?

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

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

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

非常感谢,

1 个答案:

答案 0 :(得分:3)

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

内存始终是一维连续的字节空间。但是,访问模式取决于您如何解释数据以及如何通过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; 

因为blockIdx.ythreadIdx.y将为零。

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