以下是我的矩阵加法代码。 d_m和d_n是2个矩阵,而d_s是这两个矩阵的和。
以下是我的内核函数:
__global__ void Matrix_Add(float *d_m, float *d_n, float *d_s, long long int a, long long int b)
{
long long int i = blockIdx.y*blockDim.y + threadIdx.y;
long long int j = blockIdx.x*blockDim.x + threadIdx.x;
if((i<a) && (j<b))
{
*(d_s + i*b + j) = *(d_m + i*b +j) + *(d_n + i*b + j);
}
}
以下是我的内核启动:
dim3 DimGrid(ceil(a/16),ceil(b/16),1);
dim3 DimBlock(16,16,1);
Matrix_Add<<<DimGrid,DimBlock>>>(d_m,d_n,d_s,a,b);
我只求和,直到最接近的16的倍数,其余所有和为0。
例如,如果给出2个5 * 5矩阵作为输入,则总和将为5 * 5矩阵 所有元素都为0。
仅当矩阵为16 * 16、32 * 16、16 * 32. 32 * 32等(32的倍数)时有效
那么我该如何照顾发射的最后一组块以满足边界条件?
答案 0 :(得分:2)
问题是您的网格大小计算严重中断,因此您没有运行足够的块(或者在a或b小于16的情况下启动失败。)
此:
dim3 DimGrid(ceil(a/16),ceil(b/16),1);
正在对整数除法的结果执行ceil
操作。除法过程中已经发生了截断,因此无法进行ceil
调用的舍入。例如
a = 20, b = 17
ceil(a/16) = ceil(20/16) = ceil(1) = 1
ceil(b/16) = ceil(27/16) = ceil(1) = 1
因此仅运行1个块,并且某些输入数据从不处理(或者如果a或b小于16,则将尝试启动0个块,这是运行时错误)。
将块计算更改为以下内容:
dim3 DimGrid((a + 15) / 16, (b + 15) / 16 ,1);
您可以简单地通过在运行时打印出DimGrid
的值来为自己诊断。