我正在多次(30)次启动一组内核。 这些30的每个测试(它们都是确定性的,在每次测试时都会调用一组内核10次并且这个数字是固定的),在开始时,我做cudaSetDevice(0)并且一切都得到malloc'd和memcpy'd。 测试完成并执行时间后,所有内容都是cudaFree'd。
以下是我的程序的示例输出:
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);
}
修改
mallocs,copys和其他东西没有定时。我只计算执行时间(内核启动和同步)。
启用Visual Studio 2010的优化功能。一切都设定为最大化速度。 CUDA的优化也在进行中。
答案 0 :(得分:1)
使用QueryPerformanceTime
测量内核执行时间是错误的,因为主机呼叫设备和它们并行工作。你可以只测量通话时间。
要检查内核执行时间,请使用ahmad提到的cudaEvents
:
cudaEvent_t start, stop;
float time;
cudaEventCreate(&start);
cudaEventCreate(&stop);
...
cudaEventRecord(start, 0);
yourkernel <<< n_blocks, block_size >>> (a_d, N);
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
...
cudaEventElapsedTime(&time, start, stop);
printf ("Time for the kernel: %f ms\n", time);
如果您想使用QueryPerformanceTime
,则必须致电
cudaDeviceSynchronize();
内核调用后。它会等到内核停止。