测量CUDA分配时间

Measuring CUDA Allocation time

本文关键字:时间 分配 CUDA 测量      更新时间:2023-10-16

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

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

我认为我不应该使用cuda事件,因为它们用于计时GPU进程,而不适合计时cpu调用(如果我错了,请纠正我。(如果我可以只在mallocManaged上使用cudaEvents,那么在计时new调用时,比较什么最准确?我只是对内存分配和时间安排了解不够。由于boost和nvidia的劣质文档,我读到的所有内容似乎都让我更加困惑。

您可以使用CUDA事件来测量在主机中执行的函数的时间。

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

更多信息,请访问:http://docs.nvidia.com/cuda/cuda-runtime-api/index.html

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

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

CUDA工具包附带的探查器"nvprof"可能有助于了解和优化CUDA应用程序的性能。

更多信息,请访问:http://docs.nvidia.com/cuda/profiler-users-guide/index.html

我推荐:

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

这将以秒为单位输出差值,表示为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() << "sn";

也就是说,您的实现能以多快的速度获得当前时间?如果速度较慢,则两个连续调用将显示其间的较长时间。在我的系统上(在-O3(,输出顺序为:

1.2e-07s

这意味着我可以为大约1微秒的东西计时。为了获得比这更精细的测量,我必须循环许多操作,并除以操作的数量,减去循环开销(如果这很重要的话(。

如果您对std::chrono::high_resolution_clock的实现似乎不令人满意,那么您可以根据这一点构建自己的chrono时钟。缺点显然是有点不便于携带。但是,您可以免费获得std::chronodurationtime_point基础设施(时间算术和单位转换(。