c++ 为什么CUDA共享内存在平铺矩阵乘法中比全局内存慢?

pxiryf3j  于 2023-05-20  发布在  其他
关注(0)|答案(1)|浏览(168)

我有平铺矩阵乘法代码与共享内存和不共享内存。下面是使用全局内存的矩阵乘法:

__global__ 
void MatrixMulKernel(float* M, float* N, float* P, int Width)
{
int Row = blockIdx.y*blockDim.y + threadIdx.y;
int Col = blockIdx.x*blockDim.x + threadIdx.x;
if ((Row < Width) && (Col < Width)) {
    float Pvalue = 0;
    for (int k = 0; k < Width; ++k)
    {
        Pvalue += M[Row*Width + k] * N[k*Width + Col];
    }
    
    P[Row*Width + Col] = Pvalue;
}
}

下面是使用共享内存的矩阵乘法:

__global__
void MatrixMulKernel(float* d_M, float* d_N, float* d_P, int Width)
{
__shared__ float Mds[blockWidth][blockWidth];
__shared__ float Nds[blockWidth][blockWidth];
int tx = threadIdx.x; int ty = threadIdx.y;
int bx = blockIdx.x; int by = blockIdx.y;

int row = by * blockWidth + ty;
int col = bx * blockWidth + tx;
float pvalue = 0;

for (int m = 0; m < Width / blockWidth; ++m)
{
    Mds[ty][tx] = d_M[row * Width + m*blockWidth + tx];
    Nds[ty][tx] = d_N[(m*blockWidth + ty)*Width + col];
    __syncthreads();
    for (int k = 0; k < blockWidth; ++k)
    {
        pvalue += Mds[ty][k]*Nds[k][tx];
    }
    __syncthreads();
}
d_P[row*Width + col] = pvalue;
}

据我所知,使用共享内存应该更快,但在比较这两个代码时,我发现没有共享内存的代码在1600x1600矩阵上运行快了2秒。有没有什么原因可以解释这种速度差异或者我的代码出了什么问题?
我的老师以《大规模并行处理器编程》一书为主要教材,这两个代码就是从那来的。

编辑:

内核的启动配置:

int NumBlocks =ceil( Width / blockWidth);  // blockWidth = 16
dim3 dimGrid(NumBlocks, NumBlocks,1); // Width = 1600
dim3 dimBlock(blockWidth, blockWidth,1);
clock_t startGpuCalculation = clock();
MatrixMulKernel <<<dimGrid, dimBlock >>>(d_M, d_N, d_P, Width);
cudaThreadSynchronize();
clock_t endGpuCalculation = clock();
2skhul33

2skhul331#

我在调试模式下运行项目(VS 2017和CUDA 9)。我在释放模式下运行代码,共享内存比全局内存快得多。我的错。

相关问题