线程只能以16的倍数工作

时间:2018-08-12 07:01:01

标签: cuda

以下是我的矩阵加法代码。 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的倍数)时有效

那么我该如何照顾发射的最后一组块以满足边界条件?

1 个答案:

答案 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的值来为自己诊断。