繁体   English   中英

CUDA矩阵乘法给出了错误的答案

[英]Cuda matrix multiplication gives wrong answer

更新!

我当前的代码不检查内存访问范围。 当我运行cuda memcheck时,它说即使对于2 x 2的矩阵,内存访问也很糟糕! 我正在以某种方式访问​​内存,这就是问题所在!

要检查超出范围的内存访问,请运行cuda-memcheck ./(在此处插入可执行文件)

下面显示的是我的矩阵乘法本身的代码:

dim3 block(32,32);
dim3 grid( (n+31)/32, (n+31)/32 );
matrixMul<<<grid,block>>>(d_C, d_A, d_B, n, k);

kA和kB是其中包含值的矩阵(为了方便起见,它们全为2)。

对于我的平方矩阵,m,n,k都相同

kC是存储答案的矩阵。

#ifndef _MATRIXMUL_KERNEL_H_
#define _MATRIXMUL_KERNEL_H_

#include <stdio.h>

__global__ void matrixMul(float *kC, float *kA, float *kB, int n, int k)
{

    int tx = blockIdx.x * 32 + threadIdx.x;
    int ty = blockIdx.y * 32 + threadIdx.y;
    float value = 0;

    for (int i=0;i<n;i++)
    {
        float elementA=kA[ty*n+i];
        float elementB=kB[i*k+tx];
        value += elementA*elementB;
    }

    kC[ty*n+tx] = value;
}

#endif // #ifndef _MATRIXMUL_KERNEL_H_

根据定义线程网格的方式,应将线程检查添加到内核代码中,如下所示:

#ifndef _MATRIXMUL_KERNEL_H_
#define _MATRIXMUL_KERNEL_H_

#include <stdio.h>

__global__ void matrixMul(float *kC, float *kA, float *kB, int n, int k)
{

    int tx = blockIdx.x * 32 + threadIdx.x;
    int ty = blockIdx.y * 32 + threadIdx.y;

    if ((ty < n) && (tx < n)) { // add this line
      float value = 0;

      for (int i=0;i<n;i++)
      {
        float elementA=kA[ty*n+i];
        float elementB=kB[i*k+tx];
        value += elementA*elementB;
      }

      kC[ty*n+tx] = value;
    }  //  add this line
}

#endif // #ifndef _MATRIXMUL_KERNEL_H_

否则,有效数组数组之外的线程将破坏您的结果。 事情适用于32x32的倍数,因为没有无效的线程。 在这种情况下,您正在启动所需数量的线程。 但是在其他情况下,您将启动额外的线程。 如果允许这些多余的线程计算无效的矩阵位置,则会破坏结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM