我有一個CUDA內核,它將兩個矩陣相乘,其中Width和Height是我使用的塊大小的倍數。CUDA理論帶寬vs有效帶寬
基於NVIDIA Quadro Fx的3800我使用了50 Gb/s的理論帶寬,我有一些奇怪的結果(有效帶寬比理論帶寬大)
我將張貼在這裏的一些結果:
隨着塊大小2
[10] [10] * [10] [10] - > BW = 0,02 Gb/s的[1000] [1000] * [1000] [1000] - > BW = 69,4 Gb/s
隨着塊大小64
[1000] [1000] * [1000] [1000] - > BW = 486,4 Gb/s的 [10000] [10000] * [10000] [10000] - > BW = 45072,12 Gb/s的
我從Nvidia的最佳實踐指南的有效帶寬的式(I已經簡化,但它的等價物(除非有低級錯誤))。 我認爲內核很好,因爲它與我閱讀的一些Nvidia講座非常相似(如果不相等),也因爲它的正常工作(afaik)。
#define blocksize 64
#define HM (10000)
#define WM (10000)
#define WN (10000)
#define HN WM
#define WP WN
#define HP HM
#define PTH WM
#define PTW HM
__global__ void nonsquare(float*M, float*N, float*P, int uWM,int uWN)
{
__shared__ float MS[blocksize][blocksize];
__shared__ float NS[blocksize][blocksize];
int tx=threadIdx.x, ty=threadIdx.y, bx=blockIdx.x, by=blockIdx.y;
int rowM=ty+by*blocksize;
int colN=tx+bx*blocksize;
int Pvalue=0;
for(int m=0; m< uWM/blocksize;m++){
MS[ty][tx]=M[rowM*uWM+(m*blocksize+tx)];
NS[ty][tx]=M[colN + uWN*(m*blocksize+ty)];
__syncthreads();
for(int k=0;k<blocksize;k++)
Pvalue+=MS[ty][k]*NS[k][tx];
P[rowM*WP+colN]=Pvalue;
}
}
int main(){
cudaEvent_t evstart, evstop;
cudaEventCreate(&evstart);
cudaEventCreate(&evstop);
float*M=(float*)malloc(sizeof(float)*HM*WM);
float*N=(float*)malloc(sizeof(float)*HN*WN);
for(int i=0;i<WM*HM;i++)
M[i]=(float)i;
for(int i=0;i<WN*HN;i++)
N[i]=(float)i;
float*P=(float*)malloc(sizeof(float)*HP*WP);
float *Md,*Nd,*Pd;
cudaMalloc((void**)&Md,HM*WM*sizeof(float));
cudaMalloc((void**)&Nd,HN*WN*sizeof(float));
cudaMalloc((void**)&Pd,HP*WP*sizeof(float));
cudaMemcpy(Md,M,HM*WM*sizeof(float),cudaMemcpyHostToDevice);
cudaMemcpy(Nd,N,HN*WN*sizeof(float),cudaMemcpyHostToDevice);
dim3 dimBlock(blocksize,blocksize);//(tile_width , tile_width);
dim3 dimGrid(WN/dimBlock.x,HM/dimBlock.y);//(width/tile_width , width/tile_witdh);
cudaEventRecord(evstart,0);
nonsquare<<<dimGrid,dimBlock>>>(Md,Nd,Pd,WM,WN);
cudaEventRecord(evstop,0);
cudaEventSynchronize(evstop);
float time;
cudaEventElapsedTime(&time,evstart,evstop);
cudaMemcpy(P,Pd,WP*HP*sizeof(float),cudaMemcpyDeviceToHost);
cudaFree(Md);
cudaFree(Nd);
cudaFree(Pd);
printf("\ntime spent:%f",time);
float Bandwidth=(HM*WM*4+WN*HN*4+HP*WP*4)/(time*1000000);/
printf("\nEffective Bandwidth:%f Gb/s\n",Bandwidth);
}
在此先感謝
你的問題是? – 2011-03-22 18:23:21
有效帶寬如何超過理論帶寬?我認爲理論帶寬是顯卡能達到的最大值,還是我錯了? – Bernardo 2011-03-22 18:54:11