我需要对使用 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 时,我只会使用一个索引?
非常感谢,
您在内存中排列数据的方式与您将如何配置内核线程无关。
内存总是一维连续的字节空间。但是,访问模式取决于您如何解释数据以及您如何通过 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 线程块访问它们。