1

我正在多次(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);
}

编辑:

malloc、副本和其他东西没有被计时。我只计算执行时间(内核启动和同步)。

Visual Studio 2010 的优化已打开。一切都设置为最大化速度。CUDA 的优化也在进行中。

4

1 回答 1

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();

在内核调用之后。它将等到内核停止。

于 2012-11-16T07:47:58.690 回答