2012-04-30 19 views
3
私のCUDAコードが

CUDAのGPU CPU

私のデスクトップ構成はi7の2600である私のCPUコードよりも実行速度が遅い、なぜ私はトラブルを考え出すを持っています

、GeForceは560ti

よりも遅く、私のコードは次のとおりです。

int** kernel_shiftSeam(int **MCEnergyMat, int **newE, int *seam, int width, int height,  int direction) 
{ 
//time measurement 
float elapsed_time_ms = 0; 
cudaEvent_t start, stop; //threads per block 

dim3 threads(16,16); 
//blocks 
dim3 blocks((width+threads.x-1)/threads.x, (height+threads.y-1)/threads.y); 

int *device_Seam; 

int *host_Seam; 

int seamSize; 
if(direction == 1) 
{ 
    seamSize = height*sizeof(int); 
    host_Seam = (int*)malloc(seamSize); 
    for(int i=0;i<height;i++) 
    host_Seam[i] = seam[i]; 
} 
else 
{ 
    seamSize = width*sizeof(int); 
    host_Seam = (int*)malloc(seamSize); 
    for(int i=0;i<width;i++) 
     host_Seam[i] = seam[i]; 
} 

cudaMalloc((void**)&device_Seam, seamSize); 
cudaMemcpy(device_Seam, host_Seam, seamSize, cudaMemcpyHostToDevice); 

global_host_MC = MCEnergyMat; 
new_host_MC = newE; 

//copy host array to device 
cudaMemcpy(global_MC, global_MC2, sizeof(int*)*width, cudaMemcpyHostToDevice); 
    for(int i=0;i<width;i++) 
     cudaMemcpy(global_MC2[i], global_host_MC[i], sizeof(int)*height, cudaMemcpyHostToDevice); 

cudaMemcpy(new_MC, new_MC2, sizeof(int*)*width, cudaMemcpyHostToDevice); 
    for(int i=0;i<width;i++) 
     cudaMemcpy(new_MC2[i], new_host_MC[i], sizeof(int)*height, cudaMemcpyHostToDevice); 


cudaEventCreate(&start); 
cudaEventCreate(&stop); 
cudaEventRecord(start, 0); 

//do some operations on the 2d matrix 
gpu_shiftSeam<<< blocks,threads >>>(global_MC, new_MC, device_Seam, width, height); 

//measure end time for cpu calcuations 
cudaEventRecord(stop, 0); 
cudaEventSynchronize(stop); 
cudaEventElapsedTime(&elapsed_time_ms, start, stop); 

execTime += elapsed_time_ms; 

//copy out the data back to host (RESULT) 
for(int i=0;i<width;i++) 
{ 
    cudaMemcpy(newE[i], new_MC2[i], sizeof(int)*height, cudaMemcpyDeviceToHost); 
} 

return newE; 
} 

私はそれを800回ループし、私は次の結果を得た:

GPU 計算時間(gpu_shiftseam部):1176ms 総プログラム実行時間:22S

CPU 計算時間(gpu_shiftseamとしてではなく、ホスト上の同じ動作):12S

はどうやらGPUの計算時間は、CPU上のものより道短いです: 総プログラム実行時間を12522ms 、しかし 何らかの理由でgpuのプログラム実行時間が長くなってしまったのですが、 誰がその理由を知っていますか?それは私が割り当てているスレッド/ブロックの数のためです が間違っていますか?または、デバイスにメモリを割り当てることから "遅さ"が生じていますか?

ありがとうございます!

+2

タイマーを移動したり、タイマーを作成するだけで、どこに時刻が来るかを確認できます。 cudaMemcpy()の呼び出しで時間が使用されている可能性があります。 –

+0

あなたが言ったように、時間がcudaMemcpy()コールで使用されたらどうなりますか?その機能を使ってこの時間を費やすことは避けられませんか?なぜなら私はtheresをcudaMemcpy()の代わりと考えていないからです。 –

+0

最適化する前に、kernel_shiftSeamのサブセクションの時間を計るか、プロファイラ(Parallel Nsight、CUDAプロファイラ、NVIDIA Visual Profiler)を使用します。 –

答えて

2

私の経験では、メモリアクセスが遅い理由の1つです。

どのくらいの時間が費やされているかを調べるには、配列のコピーをプロファイルします。相当な量の場合は、コードを最適化してみてください。 forループの内部をコピーする代わりに、sizeof(int *) * height * widthを直接コピーできるかどうかを確認してください。あなたがmemcpyを呼び出す回数を減らすことは助けになるはずです。

cudaMemcpy(global_MC, global_MC2, sizeof(int*)*width, cudaMemcpyHostToDevice); 
cudaMemcpy(global_MC2, global_host_MC, sizeof(int)*height*width,cudaMemcpyHostToDevice); 
+0

返信いただきありがとうございます! sizeof(int *)* height * widthをコピーすると時間が短くなりますが、ときどき正しい出力しか得られません。forループなしでmemcpyを実行する別の方法はありますか? –

+2

時には正しい出力が生成されるだけで、同期の問題が発生する可能性があります。 – kerem

0

私は似たような経験を持っていたcudaMemcpyがなかった一方でcudaMallocがボトルネックであることがわかりました。私のデバイスでは、16 MBの割り当てに160ミリ秒かかることを覚えています。ただし、CUDAのメモリ割り当ては、実際の計算の前に、たとえば別の関数呼び出しなどで行うことができます。したがって、メモリ割り当て時間は、スピードアップ計算にcudaMemcpy演算を含めるが、全体のパフォーマンス測定値、例えばスピードアップから除去することができる。

関連する問題