我目前正在学习 CUDA,我现在专注于主机和设备吞吐量之间的内存复制。这是一个小程序(见下面的注释):
int NX=1000;
int NY=800;
int size=NX*NY;
size*=sizeof(PREC);
int threadsperbloc=512;
int blockspergrid=ceil(NX*NY/threadsperbloc);
//Allocate and instanciate host arrays
PREC *h_a;
PREC *h_b;
h_a=new PREC[NX*NY];
h_b=new PREC[NX*NY];
for (int i=0;i<NX*NY;i++){
h_a[i]=i;
h_b[i]=i;
}
//Allocate device arrays and a paged-locked host array to fetch results
PREC *d_a=NULL;
PREC *d_b=NULL;
PREC *d_c=NULL;
PREC *dh_c=NULL;
CUDA_CHECK(cudaMalloc(&d_a,size));
CUDA_CHECK(cudaMalloc(&d_b,size));
CUDA_CHECK(cudaMalloc(&d_c,size));
CUDA_CHECK(cudaMemcpy(d_a, h_a, size, cudaMemcpyHostToDevice));
CUDA_CHECK(cudaMemcpy(d_b, h_b, size, cudaMemcpyHostToDevice));
CUDA_CHECK(cudaHostAlloc(&dh_c,size,cudaHostAllocDefault));
//A little addition vector addition on the device
vecadd<<<blockspergrid,threadsperbloc>>>(d_a, d_b, d_c, NX*NY);
//Repeating copies from device to page-locked host memory
for(int t=0;t<30;t++){
CUDA_CHECK(cudaMemcpy(dh_c,d_c,size,cudaMemcpyDeviceToHost));
}
cout<<"Check : "<<h_a[1000]<<" + "<< h_b[1000]<<" = "<<dh_c[1000]<<endl;
注意:PREC 是一个宏(在这种情况下是浮点数)。仅使用一个流(主要流)。在这种情况下我不使用异步,这不是重点。(我已经尝试过,但吞吐量没有改变)。
通过这个我认为正确的小测试(并提供正确的数值结果),Visual Profiler 告诉我我只有 1.52 GB/s 的吞吐量(带有“注意”图标),每次传输大约 3MB(仅供参考)。但是使用 SDK 中的 NVIDIA bandWidthTest 它说
Device to Host Bandwidth, 1 Device(s)
PINNED Memory Transfers
Transfer Size (Bytes) Bandwidth(MB/s)
33554432 3177.5
我有 3.0 的计算能力,也想实现 3.smth GB/s 的吞吐量。我检查了一点bandWidthTest.cu,但我看不出我在做什么不同(他们正在使用MemcpyAsync,但正如我所说,我也尝试过没有不同的结果)。编辑:也许您已经看到来自 SDK 的测试正在进行大约 33MB 的传输。事实上在 10 倍。我试过 30*3MB、10*12MB,但没有变化。那么,我做错了什么?