CUDA 関数のタイミングは、CPU とは少し異なります。まず、アプリケーションの開始時に CUDA 関数を呼び出して CUDA の初期化コストを考慮しないようにしてください。そうしないと、タイミングを開始したときに初期化される可能性があります。
int main (int argc, char **argv) {
cudaFree(0);
....//cuda is initialized..
}
このようにCutilタイマーを使用します
unsigned int timer;
cutCreateTimer(&timer);
cutStartTimer(timer);
//your code, to assess elapsed time..
cutStopTimer(timer);
printf("Elapsed: %.3f\n", cutGetTimerValue(timer));
cutDeleteTimer(timer);
さて、これらの準備手順の後、問題を見てみましょう。カーネルが呼び出されると、呼び出しが GPU に配信されるまで CPU 部分が停止します。CPU も継続している間、GPU は実行を継続します。cudaThreadSynchronize(..) を呼び出すと、CPU は GPU が現在の呼び出しを終了するまで停止します。cudaMemCopy 操作では、カーネルによって埋められるべき値が要求されるため、GPU がその実行を終了する必要もあります。
kernel<<<numBlocks, threadPerBlock>>>(...);
cudaError_t err = cudaThreadSynchronize();
if (cudaSuccess != err) {
fprintf(stderr, "cudaCheckError() failed at %s:%i : %s.\n", __FILE__, __LINE__, cudaGetErrorString( err ) );
exit(1);
}
//now the kernel is complete..
cutStopTimer(timer);
そのため、停止タイマー関数を呼び出す前に同期を配置します。カーネル呼び出しの後にメモリ コピーを配置すると、メモリ コピーの経過時間にはカーネル実行の一部が含まれます。そのため、タイミング操作の後に memCopy 操作を配置できます。
カーネルの一部のセクションを評価するために使用できるプロファイラー カウンターもいくつかあります。
cuda カーネルのグローバルメモリトランザクション数をプロファイリングする方法は?
CUDA カーネルのプロファイリングと最適化の方法