0

私は現在 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 はマクロ (この場合は float) です。1 つのストリームのみが使用されます (メイン ストリーム)。この場合、非同期は使用しません。これは重要ではありません。(試してみましたが、スループットは変わりません)。

私が正しいと思う (そして正しい数値結果を提供する) この小さなテストでは、Visual Profiler は、スループットが 1.52 GB/秒 (「注意」アイコン付き) しかなく、各転送が約 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を使用していますが、私が言ったように、私も別の結果で試しました)。EDIT : SDK からのテストで約 33MB の転送が行われていることを見たことがあるかもしれません。実質10回で。30*3MB、10*12MB を試しましたが、変化はありません。それで、私は何を間違っていますか?

4

1 に答える 1

0

問題は、実際には別の PC プロセスにありました。非ディスプレイ GPU で試したところ、問題なく動作しました。

于 2013-07-29T12:38:45.477 に答える