【发布时间】:2015-09-19 20:37:12
【问题描述】:
#include<stdio.h>
#include<cuda_runtime.h>
#include<sys/time.h>
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
if (code != cudaSuccess)
{
fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
if (abort) exit(code);
}
}
double measure_time()
{
struct timeval tp;
gettimeofday(&tp,NULL);
return ((double)tp.tv_sec+(double)tp.tv_usec*1.e-6);
}
__global__ void sum_matrix(int *a,int *b,int *c,int nx,int ny)
{
int ix=blockIdx.x*blockDim.x+threadIdx.x;
int iy=blockIdx.y*blockDim.y+threadIdx.y;
int idx=iy*nx+ix;
c[idx]=a[idx]+b[idx];
}
int main(int argc, char *argv[])
{
int dimx=atoi(argv[1]);
int dimy=atoi(argv[2]);
int nx=4096;
int ny=4096;
dim3 block (dimx,dimy);
dim3 grid (nx/dimx,ny/dimy);
double start,end;
int *a,*b,*c;
long long nbytes=nx*ny*sizeof(int);
cudaMalloc((int**)&a,nbytes);
cudaMalloc((int**)&b,nbytes);
cudaMalloc((int**)&c,nbytes);
start=measure_time();
sum_matrix<<<grid,block>>>(a,b,c,nx,ny);
cudaDeviceSynchronize();
gpuErrchk( cudaPeekAtLastError() );
end=measure_time();
printf("Time elapsed = %f ms\n",(end-start)*1000);
cudaFree(a);
cudaFree(b);
cudaFree(c);
return 0;
}
上面是一个二维矩阵加法内核,我用它来检查 MSI GTX 750 1 GB GDDR5 卡上不同块大小配置的执行时间。以下是不同块大小配置的执行时间结果。
./sum_matrix 32 32 经过的时间 = 3.028154 毫秒
./sum_matrix 32 16 经过的时间 = 3.180981 毫秒
./sum_matrix 16 32 经过的时间 = 2.942085 毫秒
./sum_matrix 16 16 经过的时间 = 3.238201 毫秒
./sum_matrix 64 8 经过的时间 = 3.020048 毫秒
./sum_matrix 64 16 经过的时间 = 3.304005 毫秒
./sum_matrix 128 2 经过的时间 = 2.965927 毫秒
./sum_matrix 128 1 经过的时间 = 2.896070 毫秒
./sum_matrix 256 2 经过的时间 = 3.004074 毫秒
./sum_matrix 256 1 经过的时间 = 2.948046 毫秒
我可以理解的是,将块大小增加到最大(1024 个线程),例如 (64,16) 可能会降低可用并行度,因此性能会更差。我不明白为什么增加块 x 尺寸和减少块 y 会提供更好的性能。是由于内存合并/缓存还是发散?
谢谢
【问题讨论】:
-
您在动态时钟游戏卡上运行。这使得计时结果非常不稳定。