2016-05-09 6 views
1

私はNVS 5400Mを入手しましたが、行列(インスタンス1000 x 1000)でのcuda加算の信頼できる時間測定結果を得ようとしています。CudaEventElapsedTimeでのCudaカーネル時間計測

__global__ void MatAdd(int** A, int** B, int** C) { 
int i = threadIdx.x; 
int j = threadIdx.y; 
C[i][j] = A[i][j] + B[i][j]; } 

そして、私のような測定をやってる:

int numBlocks = 1; 
dim3 threadsPerBlock(1000, 1000); 

float time; 
cudaEvent_t start, stop; 
cudaEventCreate(&start); 
cudaEventCreate(&stop); 
cudaEventRecord(start, 0); 

MatAdd <<<numBlocks, threadsPerBlock>>>(pA, pB, pC); 

cudaEventRecord(stop, 0); 
cudaEventSynchronize(stop); 
cudaEventElapsedTime(&time, start, stop); 

cout << setprecision(10) << "GPU Time [ms] " << time << endl; 

と結果は次のとおりです。比較的小さい0.001504000043 MS、。私の質問は正しいことですか?

答えて

1

タイミングは正しいですが、CUDAの使用法は一般的ではありません。

これは違法です:

dim3 threadsPerBlock(1000, 1000); 

CUDAカーネルは、ブロックあたり1024スレッドの最大に制限されていますが、ブロックごとに1000×1000 = 1,000,000スレッドを要求しています。

その結果、あなたのカーネルが実際に起動されていません。

MatAdd <<<numBlocks, threadsPerBlock>>>(pA, pB, pC); 

それで、測定時間が非常に短いです。

を使用し、cuda-memcheckでテストを実行して、ランタイムエラーが報告されていないことを確認することをお勧めします(私の推測では、コードから報告されたエラーを認識していません。 )

あなたは完全なコードを表示していないので、他に存在する可能性のある問題をすべて特定するつもりはありませんが、カーネルコードを再処理する必要があります。 1000x1000の配列を適切に使用し、ダブルポインター(例えばint** A)パラメーターをカーネルに渡すことは、単一ポインターまたは「フラット」配列よりもかなり困難です。

+0

cudError_tを確認した後、私はメッセージを受け取りました:sync kernel error:無効な設定引数。 ありがとうございます! – azet52

+0

@編集:私は 'dim3 threadsPerBlock(32,32)' に変更しました。実際のコードは です。int ** A = create_random_matrix(1000); ' ' int ** pA = initialize_matrix(1000); ' 'cudaMalloc((void *)pA、(1000 * 1000)* sizeof(int)); ' cudaMemcpy(pA、A、(1000 * 1000)* sizeof(int)、cudaMemcpyHostToDevice) ' 同じ(C、PC、(1000 * 1000)* sizeof(int)、cudaMemcpyDeviceToHost);'MatAdd <<< numBlocks、threadsPerBlock >>>(pA、pB、pC); cudaMemcpy ; 受信しました:無効な引数と不正なメモリアクセスがエンコードされました – azet52

+0

カーネルへのダブルポインタ引数を正しく管理する方法が理解できないため、不正なメモリアクセスです。深いコピーが必要です。わかりやすくするために、私はあなたの配列を単一の添字で参照できるように平坦化することをお勧めします。表示されていないコードや新しい問題について助けが必要な場合は、新しい質問を投稿することをお勧めします。 –

関連する問題