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

Cuda块/网格尺寸:何时使用dim3?,cuda,gpu,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 *

关于使用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>>>(...)
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
当我不使用dim3时,我只使用一个索引


非常感谢,

在内存中安排数据的方式独立于如何配置内核线程

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

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

块和网格也会发生同样的情况

更多信息请访问:

因此,在这两种情况下:
dim3 blockDims(512)
myKernel(…)
您将始终可以访问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.y
threadIdx.y
将为零

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

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

int gid = img.col * y + x;