C++ CUDA:为啥我的块尺寸不起作用?
Posted
技术标签:
【中文标题】C++ CUDA:为啥我的块尺寸不起作用?【英文标题】:C++ CUDA: Why aren't my block dimensions working?C++ CUDA:为什么我的块尺寸不起作用? 【发布时间】:2022-01-16 11:09:59 【问题描述】:我正在使用书中的一个示例来解决 4x4 矩阵乘法。然而,这本书只提供了内核代码,所以剩下的程序就交给我了。这本书说使用 2 的块宽度,但是我不能让它与 dim3 变量一起使用。这是内核:
__global__ void matmul_basic(float *c, float *a, float *b, unsigned int width)
printf("Width: %d\n", width);
printf("BlockDim.x: %d, BlockDim.y: %d, BlockDim.z: %d\n", blockDim.x, blockDim.y, blockDim.z);
printf("GridkDim.x: %d, GridDim.y: %d, GridDim.z: %d\n", gridDim.x, gridDim.y, gridDim.z);
printf("Blockidx.x: %d, Blockidx.y: %d, Blockidx.z: %d\n", blockIdx.x, blockIdx.y, blockIdx.z);
printf("threadIdx.x %d, threadIdx.y: %d, threadIdx.z: %d\n", threadIdx.x, threadIdx.y, threadIdx.z);
// Calculate the row index of the c element and a
int Row = blockIdx.y * blockDim.y + threadIdx.y;
// Calculate the column index of c and b
int Col = blockIdx.x * blockDim.x + threadIdx.x;
// Sense check
printf("Row: %d\tCol: %d\n", Row, Col);
if ((Row < width) && (Col < width))
float Pvalue = 0;
// each thread computes one element of the block sub-matrix
for (size_t k = 0; k < width; k++)
Pvalue += a[Row * width + k] * b[k * width + Col];
c[Row * width + Col] = Pvalue;
else
printf("Dimensions out of bounds. Row: %d, Col: %d\n", Row, Col);
我知道打印语句过多,但我只是想验证尺寸。以下是函数调用中的维度:
dim3 dimGrid = (1, 1, 1);
dim3 dimBlock = (2, 2, 1);
matmul_basic <<<dimGrid, dimBlock>>> (d_c, d_a, d_b, width);
这应该是一个 2x2 维度的线程块? 最后,这是读数:
Width: 4
BlockDim.x: 1, BlockDim.y: 1, BlockDim.z: 1
GridkDim.x: 1, GridDim.y: 1, GridDim.z: 1
Blockidx.x: 0, Blockidx.y: 0, Blockidx.z: 0
threadIdx.x 0, threadIdx.y: 0, threadIdx.z: 0
Row: 0 Col: 0
Kernel Complete, transferring results...
20218 -1.07374e+08 -1.07374e+08 -1.07374e+08
-1.07374e+08 -1.07374e+08 -1.07374e+08 -1.07374e+08
-1.07374e+08 -1.07374e+08 -1.07374e+08 -1.07374e+08
-1.07374e+08 -1.07374e+08 -1.07374e+08 -1.07374e+08
所以它永远不会超过第一个线程,它认为块大小是 1x1x1?它也永远不会进入表明它在矩阵维度之外的 else 语句。
我确定我在做一些愚蠢的事情,或者我误解了维度的工作原理。任何帮助将不胜感激。谢谢!
编辑: 从 printf 语句中添加宽度初始化和读出:
初始化:
// Determine matrix dimensions
const int width = 4;
上面原始部分中的读数已被编辑为包括宽度。
【问题讨论】:
“读数”似乎缺少第一行(printf("Width: %d\n", width);
的输出)。这可能很重要,因为在您的帖子中没有其他地方,您是否向我们展示了您为 width
变量赋值的位置。
@AdrianMole 你是对的,对不起。我现在已将其添加到编辑中。
【参考方案1】:
它认为块大小是 1x1x1?
是的。
为什么我的块尺寸不起作用?
因为:
dim3 dimBlock = (2, 2, 1);
没有做你认为它正在做的事情,而且它不是初始化dim3
变量的正确方法。您可能想花点时间思考一下 C++ 中的表达式 (2,2,1)
求值 是什么。在引擎盖下,dim3
变量是具有 3 个组件的struct
。您不能在 C++ 中以这种方式设置 3 元素结构的所有 3 个组件。
无论如何,你会遇到这样的事情会更好,它会调用构造函数来设置值:
dim3 dimBlock(2, 2, 1);
或者这个,哪个没有:
dim3 dimBlock;
dimBlock.x = 2;
dimBlock.y = 2;
dimBlock.z = 1;
我还要指出,对于 4x4 问题,您的网格大小也不正确,但您可能会弄清楚。
【讨论】:
非常感谢,这是我的一个愚蠢的误读。对此还是很陌生!你对网格大小是正确的,还没有解决这个问题。你让我头疼了,再次感谢!以上是关于C++ CUDA:为啥我的块尺寸不起作用?的主要内容,如果未能解决你的问题,请参考以下文章