しばらくの間cudaを学び始めましたが、次の問題があります
以下で私がどのようにやっているかを見てください:
GPUをコピーする
int* B;
// ...
int *dev_B;
//initialize B=0
cudaMalloc((void**)&dev_B, Nel*Nface*sizeof(int));
cudaMemcpy(dev_B, B, Nel*Nface*sizeof(int),cudaMemcpyHostToDevice);
//...
//Execute on GPU the following function which is supposed to fill in
//the dev_B matrix with integers
findNeiborElem <<< Nblocks, Nthreads >>>(dev_B, dev_MSH, dev_Nel, dev_Npel, dev_Nface, dev_FC);
CPUを再度コピーします
cudaMemcpy(B, dev_B, Nel*Nface*sizeof(int),cudaMemcpyDeviceToHost);
- 配列Bをdev_Bにコピーするのにかかる時間は、ほんの一瞬です。ただし、配列dev_BをBにコピーするのは永遠にかかります。
findNeiborElem関数には、各スレッドのループが含まれます。たとえば、次のようになります。
__ global __ void findNeiborElem(int *dev_B, int *dev_MSH, int *dev_Nel, int *dev_Npel, int *dev_Nface, int *dev_FC){ int tid=threadIdx.x + blockIdx.x * blockDim.x; while (tid<dev_Nel[0]){ for (int j=1;j<=Nel;j++){ // do some calculations B[ind(tid,1,Nel)]=j// j in most cases do no go all the way to the Nel reach break; } tid += blockDim.x * gridDim.x; } }
それについて非常に奇妙なのは、dev_BをBにコピーする時間は、jインデックスの反復回数に比例するということです。
たとえば、その場合Nel=5
、時間は約5 sec
です。
増やすとNel=20
時間は約20 sec
です。
コピー時間は、Matrixの値を割り当てるために必要な内部反復とは無関係である必要がありますdev_B
。
また、同じマトリックスをCPUとの間でコピーする時間も同じオーダーになると思います。
何が悪いのか分かりますか?