一連のカーネルを複数回 (30 回) 起動しています。これらの 30 のすべてのテスト (それらは決定論的であり、すべてのテストで一連のカーネルが 10 回呼び出され、この数は固定されています) の最初に、cudaSetDevice(0) を実行すると、すべてが malloc および memcpy されます。テストが完了し、実行時間が取られると、すべてが cudaFree になります。
私のプログラムからのサンプル出力は次のとおりです。
avg: 81.7189
times:
213.0105 202.8020 196.8834 202.4001 197.7123 215.4658 199.5302 198.6519 200.8467
203.7865 20.2014 20.1881 21.0537 20.8805 20.1986 20.6036 20.9458 20.9473 20.292
9 20.9167 21.0686 20.4563 24.5359 21.1530 21.7075 23.3320 20.5921 20.6506 19.933
1 20.8211
最初の 10 個のカーネルは約 200 ミリ秒かかり、他のカーネルは約 20 ミリ秒かかります。
どうやらすべてのカーネルが同じ値を計算し、すべて正しい値を出力します。しかし、すべてのテストを同じ順序で malloc したため、GPU メモリは前回の実行と同じ値のままではないでしょうか?
また、カーネルをチェックしているため、カーネルはエラーを返しません。すべてのカーネルの起動には、デバッグの目的で cudaThreadSynchronize() があり、その直後に次のマクロを使用してエラー チェックを行います。
#define CUDA_ERROR_CHECK if( (error = cudaGetLastError()) != cudaSuccess) printf("CUDA error: %s\n", cudaGetErrorString(error));
なぜこうなった?
Windows関数から実行時間を取得しています:
void StartCounter()
{
LARGE_INTEGER li;
if(!QueryPerformanceFrequency(&li))
cout << "QueryPerformanceFrequency failed!\n";
PCFreq = double(li.QuadPart)/1000.0;
QueryPerformanceCounter(&li);
CounterStart = li.QuadPart;
}
void StopCounter()
{
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
double time = double(li.QuadPart-CounterStart)/PCFreq;
v.push_back(time);
}
編集:
malloc、コピー、およびその他のものは時間計測されていません。実行時間のみを計測します (カーネルの起動と同期)。
Visual Studio 2010 の最適化がオンになっています。すべてが速度を最大化するように設定されています。CUDA の最適化もオンになっています。