繁体   English   中英

CUDA和线程阻塞开销

[英]CUDA and thread blocks overhead

我已经实现了一个计算矩阵乘法的简单内核。 这是代码:

__global__ void MatMultKernel(Mat A, Mat B, Mat C){

int i;
double val=0.0;
int ix=blockDim.x*blockIdx.x+threadIdx.x;  
int iy=blockDim.y*blockIdx.y+threadIdx.y;
if(ix<A.nrows && iy<B.nrows){
    for(i=0;i<A.nrows;i++)
        val+=A.value[iy*A.nrows+i]*B.value[i*B.nrows+ix];
    C.value[iy*C.nrows+ix]=val;
 }
}

我通过改变线程和块配置来测量这个内核的运行时间。

如果线程在列块中分配(例如dim3(1,256,1)),我看到执行时间总是更糟糕。这是什么原因?

首先,我要指出您的代码仅适用于方形矩阵,通常您应该在代码的所有三个位置使用A.ncols而不是A.nrows

性能差异是由于内存访问。 你必须存储在行主要格式的所有三个矩阵和代码执行以下操作:每个线程访问iy的排第Aix的列处B ,并计算它们的点积。 请注意,warp中的所有线程总是同时执行相同的指令,因此在代码中的串行循环中,对于warp中的所有线程, i总是相同的。 在您的代码中,块形状很重要,因为:

  • 如果块大小是(256, 1, 1) ,则块中的每个线程具有相同的iy ,但是ix不同。 让我们看一下B的访问模式:同一个warp中的所有线程总是访问B的同一行,因为在B.value[i*B.nrows+ix]i是相同的而且ix不同,所以负载可以合并
  • 如果块大小为(1, 256, 1) ,则情况会被转置,因此您可能希望合并来自A的负载。 但事实并非如此,因为iy确定了行,并且两个相邻线程访问的值被A.ncols偏移。

到接入图案C是一样的B ,但较不重要。 对于2D块,情况介于两个1D案例之间。

如果要进一步优化代码,可以使用“ CUDA编程指南”中所示的共享内存。

暂无
暂无

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

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