测量CUDA分配时间

时间:2015-07-07 00:20:05

标签: c++ c++11 boost cuda

我需要测量使用new分配正常CPU内存和调用cudaMallocManaged之间的时差。我们正在使用统一内存,并试图找出将事物切换到cudaMallocManaged的权衡。 (内核似乎运行得慢得多,可能是由于缺少缓存或其他原因。)

无论如何,我不确定这些分配时间的最佳方式。提升的process_real_cpu_clockprocess_user_cpu_clockprocess_system_cpu_clock会给我最好的结果吗?或者我应该只使用C ++ 11中的常规系统时间调用?或者我应该使用cudaEvent的东西来计时?

我认为我不应该使用cuda事件,因为它们用于计算GPU进程并且不能用于计时cpu调用(如果我错了那么请纠正我。)如果我可以使用cudaEvents就可以了mallocManaged one,在new呼叫计时时最准确的比较是什么?我对内存分配和时序知之甚少。由于boost和nvidia的伪劣文档,我读到的所有内容似乎都让我更加困惑。

2 个答案:

答案 0 :(得分:3)

您可以使用CUDA事件来衡量主机中执行的功能的时间。

  

cudaEventElapsedTime计算两个事件之间经过的时间(以毫秒为单位,分辨率约为0.5微秒)。

阅读详情:http://docs.nvidia.com/cuda/cuda-runtime-api/index.html

此外,如果您还对计算内核执行时间感兴趣,您会发现CUDA事件API会自动阻止代码的执行,并等待任何异步调用结束(如内核调用)。

在任何情况下,您都应该使用相同的指标(始终是CUDA事件,或者提升,或者您自己的时间)来确保相同的分辨率和开销。

探查者`nvprof'随CUDA工具包一起提供,可能有助于理解和优化CUDA应用程序的性能。

阅读详情:http://docs.nvidia.com/cuda/profiler-users-guide/index.html

答案 1 :(得分:1)

我建议:

auto t0 = std::chrono::high_resolution_clock::now();
// what you want to measure
auto t1 = std::chrono::high_resolution_clock::now();
std::cout << std::chrono::duration<double>(t1-t0).count() << "s\n";

这将输出以double表示的秒数差异。

分配算法通常在进行时优化自身。也就是说,第一次分配通常比第二次分配更昂贵,因为存储器的存储器是在第一次分配期间创建的。因此,您可能希望将循环中的时间放在一个循环中,并对结果进行平均。

std::chrono::high_resolution_clock的某些实现并不那么引人注目,但随着时间的推移而不断改进。您可以使用以下方式评估您的实施:

auto t0 = std::chrono::high_resolution_clock::now();
auto t1 = std::chrono::high_resolution_clock::now();
std::cout << std::chrono::duration<double>(t1-t0).count() << "s\n";

也就是说,您的实施能够以多快的速度获得当前时间?如果它很慢,则两次连续呼叫将显示中间的大量时间。在我的系统上(在-O3),这将按以下顺序输出:

1.2e-07s

这意味着我可以计算大约1微秒的时间。要获得比我必须遍历许多操作更精细的测量,并除以操作的数量,如果这将是重要的,则减去循环开销。

如果您std::chrono::high_resolution_clock的实施效果不理想,您可以构建自己的chrono时钟along the lines of this。缺点显然是一些不便携的工作。但是,您可以免费获得std::chrono durationtime_point基础结构(时间算术和单位转换)。