Time 相同CUDA内核执行时间之间的巨大差异

Time 相同CUDA内核执行时间之间的巨大差异,time,cuda,Time,Cuda,我将多次(30次)发布一组内核。 这30个测试中的每一个(它们都是确定性的,在每个测试中一组内核被调用10次,这个数字是固定的),开始时,我使用cudaSetDevice(0),所有东西都得到malloc'd和memcpy'd。 当测试完成,执行时间完成时,一切都是自由的 以下是我的程序的输出示例: avg: 81.7189 times: 213.0105 202.8020 196.8834 202.4001 197.7123 215.4658 199.5302 198.6519 200.84

我将多次(30次)发布一组内核。 这30个测试中的每一个(它们都是确定性的,在每个测试中一组内核被调用10次,这个数字是固定的),开始时,我使用cudaSetDevice(0),所有东西都得到malloc'd和memcpy'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);
}
void StartCounter()
{
大整数李;
if(!QueryPerformanceFrequency(&li))

cout使用
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
测量内核执行时间是错误的,因为主机调用设备和它们并行工作。您可能只测量调用时间

要检查内核执行时间,请使用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);

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

通过cudaEvents测量时间。请参阅post。您使用的是哪些窗口?您有什么类型的GPU?可能是GeForce开普勒卡吗?不是开普勒、费米、GTX 570、windows 7 64位。通过cudaEvents测量时间。请参阅post。您使用的是哪些窗口?您有什么类型的GPU?可能是吗GeForce开普勒卡?不是开普勒、费米、GTX 570、windows 7 64位。我不是在测量启动,因为每次启动内核后,我都会进行同步。在所有内核启动后,我会进行另一次同步,以确保在计算总运行时间之前执行所有内核。我在这里已经有了这个问题:@polar为什么不执行难道你不试着像响应者已经建议的那样使用cudaEvent API,看看你得到的结果是相似的还是不同的吗?另外,为什么不发布一个简单的示例(完整的可编译代码),重现你认为存在的问题?如果你仍然看到cudaEvent的使用时间不同,那么逐渐移动各种函数(例如Cudamaloc、cudaMemcpy、cudaFree)在计时循环之外,直到可变性消失。如果仅对内核计时时可变性仍然存在,则需要分析内核时间可能会发生变化的原因。您尚未发布任何此类代码。我将尽快尝试并在此处发布结果。我只对内核执行时间进行计时,而不是对malloc、copy和其他东西。几个月前我用CUDA写了我的硕士论文,我建议你试试事件。我确信这是检查执行时间的最好方法。发布你的结果,因为我很好奇。我会的。事实上,这是我的硕士论文。我不测量启动,因为每次内核启动后我都会进行同步。毕竟,内核ls已经启动,我做了另一个,以确保在计算总运行时间之前执行所有内核。我在这里已经有了这个问题:@polar为什么不按照响应者的建议尝试使用cudaEvent API,看看是否得到类似或不同的结果?另外,为什么不发布一个简单的示例(完整的可编译代码)重现您认为存在的问题?如果您仍然看到cudaEvent的时间变化,则逐渐移动各种函数(例如Cudamaloc、cudaMemcpy、cudaFree)在计时循环之外,直到可变性消失。如果仅对内核计时时可变性仍然存在,则需要分析内核时间可能会发生变化的原因。您尚未发布任何此类代码。我将尽快尝试并在此处发布结果。我只对内核执行时间进行计时,而不是对malloc、copy和其他东西。几个月前我用CUDA写了我的硕士论文,我建议你尝试一些活动。我确信这是检查执行时间的最好方法。发布你的结果,因为我很好奇。我会的。事实上,这是我的硕士论文。