nvvp显示内核代码访存带宽比较低,不知道该如何继续优化

我要处理的问题类似矩阵乘法。问题描述如下:内核是要计算B(i)*A(i)=C(i)
其中A B C都是矩阵(但是规模不是很大,i也不是很大)
A B C的存储结构为:A[n][m] B[p][n] C[p][m]
对于不同的i ,m n p 都是一样的。但是对于不同的i,B C不是满矩阵——第二维取值范围是 dp>=i&&dp<p(其他位置为空位)。
我写了一个内核,考虑了对齐、应用shared memory等问题,但是nvvp跑出来的结果显示global/DRAM load/store throughtput都比较低,不知道还能如何优化?
下面是我程序代码,以及一组可取的i m n p 值。
其中:
WFin同上面的A
DMt同上面的B
WFout同上面的C
NQA1同上面的 m,取128
NQA2同上面的 n ,取159
(J2max+1)同上面的p ,取159(J2max=158)
(Mmax+1)同上面的 i,取64(Mmax=63)
内核代码如下:

void __global__ kernel(int ldNQA1,int ldNQA2,int J2max,int Mmax,int NQA1,int NQA2,float *WFin,float *DMt, float *WFout){
  __shared__ float tmpWFin[32][32];
  __shared__ float tmpDMt[8][33];
  int tidx,tidy,bidx,bidy,bidz;
  int dblock,dNQA1,dNQA2,dj2,offset;
  float tmp=0.0f;
  tidx=threadIdx.x;
  tidy=threadIdx.y;
  bidx=blockIdx.x;
  bidy=blockIdx.y;
  bidz=blockIdx.z;

  if(bidz<=Mmax&&J2max-bidy*blockDim.y>=bidz){
   dNQA1=bidx*blockDim.x+tidx;
   dj2=J2max-bidy*blockDim.y-tidy;

   for(dblock=0;dblock<=ldNQA2-32;dblock+=32){
   if(dNQA1<NQA1){
#pragma unroll 4
   for(offset=tidy;offset<=tidy+24;offset+=8){
   dNQA2=dblock+offset;
   if(dNQA2<NQA2)
   tmpWFin[offset][tidx]=WFin[(bidz*NQA2+dNQA2)*ldNQA1+dNQA1];
   }
   }

   if(dj2>=bidz&&dj2<=J2max){
   dNQA2=dblock+tidx;
   if(dNQA2<NQA2)
   tmpDMt[tidy][tidx]=DMt[(bidz*(J2max+1)+dj2)*ldNQA2+dNQA2];
   }

   __syncthreads();
   if(dNQA1<NQA1&&dj2>=bidz&&dj2<=J2max){
#pragma unroll 32
   for(offset=0;offset<32;offset++){
   if(dblock+offset<NQA2)
   tmp+=tmpWFin[offset][tidx]*tmpDMt[tidy][offset];
   }
   }
   __syncthreads();
   }
   if(dNQA1<NQA1&&dj2>=bidz&&dj2<=J2max)
   WFout[(bidz*(J2max+1)+dj2)*ldNQA1+dNQA1]=tmp;
  }
}

调用函数代码如下:

int main(){

  int ldNQA1=((64-1)/32+1)*32*2;
  int ldNQA2=((159-1)/32+1)*32;
  int J2max=158;
  int NQA1=64*2;
  int NQA2=159;
  int Mmax=63;
  float *dWFin,*dDMt,*dWFout;
  float a;

  cudaMalloc((void **)&dWFin,sizeof(float)*ldNQA1*NQA2*(Mmax+1));
  cudaMalloc((void **)&dDMt,sizeof(float)*ldNQA2*(J2max+1)*(Mmax+1));
  cudaMalloc((void **)&dWFout,sizeof(float)*ldNQA1*NQA2*(Mmax+1));
  dim3 block,grid;
  grid=dim3((NQA1-1)/32+1,J2max/8+1,Mmax+1);
  block=dim3(32,8,1);
  kernel<<<grid,block>>>(ldNQA1,ldNQA2,J2max,Mmax,NQA1,NQA2,dWFin,dDMt,dWFout);
  cudaDeviceSynchronize();

  printf("%s\n",cudaGetErrorString(cudaGetLastError()));
  cudaMemcpy(dWFout,&a,sizeof(float),cudaMemcpyDeviceToHost);

  printf("%f\n",a);
  return 0;
}

------------------------------------------------------------------------------更改了下字体格式

我的卡是K20m,开了ecc。nvvp结果如下图:
[attach]3252[/attach]

[attach]3251[/attach]