cudaEventSynchronize 与 cudaDeviceSynchronize

Boj*_*eng 6 cuda cuda-events

我是 CUDA 的新手,对cudaEvent. 我现在有一个代码示例,如下所示:

float elapsedTime; 
cudaEvent_t start, stop;
CUDA_ERR_CHECK(cudaEventCreate(&start));
CUDA_ERR_CHECK(cudaEventCreate(&stop));

CUDA_ERR_CHECK(cudaEventRecord(start));

// Kernel functions go here ...

CUDA_ERR_CHECK(cudaEventRecord(stop));
CUDA_ERR_CHECK(cudaEventSynchronize(stop));
CUDA_ERR_CHECK(cudaEventElapsedTime(&elapsedTime, start, stop));

CUDA_ERR_CHECK(cudaDeviceSynchronize());
Run Code Online (Sandbox Code Playgroud)

我对这段代码有两个问题:

1.最后一个cudaDeviceSynchronize有必要吗?因为根据 的文档cudaEventSynchronize,其功能是等待直到最近一次调用之前的所有设备工作完成cudaEventRecord()。既然我们已经打电话了cudaEventSynchronize(stop),还需要再打电话吗cudaDeviceSynchronize

2.上面的代码与下面的实现相比有什么不同:

#include <chrono>

auto tic = std::chrono::system_clock::now();

// Kernel functions go here ...

CUDA_ERR_CHECK(cudaDeviceSynchronize());
auto toc = std::chrono::system_clock:now();

float elapsedTime = std::chrono::duration_cast < std::chrono::milliseconds > (toc - tic).count() * 1.0;
Run Code Online (Sandbox Code Playgroud)

tal*_*ies 4

只是为了充实评论,以便这个问题有答案,并且会从未回答的队列中消失:

  1. 不,cudaDeviceSynchronize()没有必要打电话。事实上,在多个流中使用异步 API 调用的许多情况下,使用全局范围同步调用是不正确的,因为您将破坏事件计时器的功能,而事件计时器允许对流中的操作进行精确计时。

  2. 他们是完全不同的。一种是使用主机端时序,另一种是使用设备驱动程序时序。在最简单的情况下,两者测量的时间具有可比性。然而,在主机端计时版本中,如果您将消耗大量时间的主机CPU操作放在主机计时部分,当GPU操作花费的时间少于主机时,您的时间测量将不会反映使用的GPU时间运营。