定时CUDA内核的策略:优点和缺点?

时间:2012-12-03 01:51:48

标签: cuda gpgpu nvidia benchmarking

在对CUDA内核进行计时时,以下方法不起作用,因为内核在执行时不会阻止CPU程序执行:

start timer
kernel<<<g,b>>>();
end timer

我已经看到了(成功)计时CUDA内核的三种基本方法:

(1)两个CUDA eventRecords。

float responseTime; //result will be in milliseconds
cudaEvent_t start; cudaEventCreate(&start); cudaEventRecord(start); cudaEventSynchronize(start);
cudaEvent_t stop;  cudaEventCreate(&stop);
kernel<<<g,b>>>();
cudaEventRecord(stop); cudaEventSynchronize(stop);
cudaEventElapsedTime(&responseTime, start, stop); //responseTime = elapsed time

(2)一个CUDA eventRecord。

float start = read_timer(); //helper function on CPU, in milliseconds
cudaEvent_t stop;  cudaEventCreate(&stop);
kernel<<<g,b>>>();
cudaEventRecord(stop); cudaEventSynchronize(stop);
float responseTime = read_timer() - start;

(3)deviceSynchronize而不是eventRecord。 (可能仅在单个流中使用编程时才有用。)

float start = read_timer(); //helper function on CPU, in milliseconds
kernel<<<g,b>>>();
cudaDeviceSynchronize();
float responseTime = read_timer() - start;

我通过实验证实这三种策略产生相同的时间结果。


问题:

  • 这些策略的权衡取舍是什么?这里有任何隐藏的细节吗?
  • 除了对多个流中的多个内核进行计时之外,使用两个事件记录和cudaEventElapsedTime()函数有什么好处吗?

你可以用你的想象力来弄清楚read_timer()的作用。然而,提供示例实现并不会有害:

double read_timer(){
    struct timeval start;
    gettimeofday( &start, NULL ); //you need to include <sys/time.h>
    return (double)((start.tv_sec) + 1.0e-6 * (start.tv_usec))*1000; //milliseconds
}

2 个答案:

答案 0 :(得分:1)

你似乎已经排除了大部分差异,说它们都会为你所展示的相对简单的情况产生相同的结果(可能不完全正确,但我理解你的意思),以及“除了时间(复杂)序列)......“第一个案例显然更好。

一个可能的区别是windows和linux之间的可移植性。我相信你的示例read_timer函数是面向linux的。您可以制作一个“便携式”的read_timer函数,但cuda事件系统(方法1)可以原样移植。

答案 1 :(得分:0)

选项(1)使用cudaEventRecord为CPU计时。这是非常低效的,我不鼓励使用cudaEventRecord来达到这个目的。 cudaEventRecord可用于计算GPU推送缓冲时间以执行内核,如下所示:

float responseTime; //result will be in milliseconds
cudaEvent_t start;
cudaEvent_t stop;
cudaEventCreate(&start);
cudaEventCreate(&stop);

cudaEventRecord(start);
kernel<<<g,b>>>();
cudaEventRecord(stop);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&responseTime, start, stop); //responseTime = elapsed time

如果您向多个流提交多个工作项,则需要稍微更改代码。我建议阅读Difference in time reported by NVVP and counters

的答案

选项(2)和(3)对于给定的例子是类似的。选项(2)可以更灵活。