あなたのマトリックスはすでにGPUに入っていますか? そうでない場合、CUBLASはそれらをあなたのために転送することがあります(サンクと呼ばれます)。これは追加のオーバーヘッドです。
また、GPUはそのような小さな計算では輝きません。つまり、結果を戻す必要があるため、おそらくCPUよりも遅くなります。 可能であれば、より大きな行列を使用してください。 それ以外の場合は、ストリーム(cudaStream_t)を使用して、GPUで複数の並列計算を開始することができます。このようなイベントで
あなたはCUDAカーネルの実行時間を計測したい場合、あなたはその(またはGPU上で計算何かを)囲む必要があり、CUDAランタイムAPIを使用して:
cudaEvent_t start, stop;
cudaEventRecord(&start);
struct timeval cpuStart, cpuEnd;
gettimeofday(&cpuStart, 0); // get start time on CPU
// Do something with CUDA on the GPU, e.g. call kernels, transfer memory, ...
gettimeofday(&cpuEnd, 0); // get end time on CPU
double seconds = cpuEnd.tv_sec - cpuStart.tv_sec;
double microseconds = cpuEnd.tv_usec - cpuStart.tv_usec;
double cpuDuration = (seconds * 1.0e6 + microseconds)/1.0e3; // in milliseconds
cudaEventRecord(&stop);
// Wait until the stop event occurred
cudaError_t eventResult;
do
{
eventResult = cudaEventQuery(stop);
}
while (eventResult == cudaErrorNotReady);
// Assert there was no error; check the CUDA Toolkit Reference for further info
assert(cudaSuccess == eventResult); // requires #include <assert.h> or <cassert>
// Retrieve the time
float gpuDuration = 0.0; // in milliseconds
cudaEventElapsedTime(&gpuDuration, start, stop);
// Release the event objects
cudaEventDestroy(stop);
cudaEventDestroy(start);
前回の呼び出しでエラーが発生したため、CUDAのすべての呼び出しのエラーコードを確認することができます(前回の呼び出しからエラーが発生する可能性があるため)...
CUDAドライバAPIは、そのままでは動作しない可能性があります。申し訳ありません)。
EDIT:ちょうどカーネルの持続時間ではなく、呼び出し自体を測定したいと思っていました。 これは、コールのCPU時間を測定することで可能です。上記の更新されたコードを参照してください。 gettimeofdayはWindows(AFAIK)では使用できないため、これはLinuxのみで動作します。
CUDAにジョブを送信するのか、それとも興味のあるものだけを動的に選択できるようにするには? – Rup
@Rup:コールが実際に費やしていることを理解することに興味があります。遅いコードが私のせいであるのか、それとも単に建築物の産物なのかを判断してください。 –
少量のデータでは、あなたの頭上だけでなく、可能な並行性が欠けています。 GPUは待ち時間を隠すのに十分なスレッドを持っていることに熱心に依存しています(これはCPUのためにGPUではかなり悪いです)。呼び出しのオーバーヘッドがなくても、作業がスレッドの**ロット**に分割されていない限り、GPUはCPUより遅くなる可能性があります。たくさんのスレッドを簡単に意味することができます。 – Grizzly