更新!
我当前的代码不检查超出范围的内存访问。当我运行cuda memcheck时,它表示即使对于2比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_
答案 0 :(得分:2)
根据您如何定义线程网格,您应该在内核代码中添加一个线程检查,如下所示:
#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的倍数,因为没有无效的线程。在这种情况下,您将准确启动所需数量的线程。但在其他情况下,您正在启动额外的线程。如果允许计算无效的矩阵位置,这些额外的线程将破坏结果。