cudaEventSynchronize 与 cudaDeviceSynchronize

标签 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());

关于这段代码,我有两个问题:

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;

最佳答案

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

  • 不,cudaDeviceSynchronize() 调用不是必需的。事实上,在多个流中使用异步 API 调用的许多情况下,使用全局范围同步调用是不正确的,因为您会破坏事件计时器的功能,这些功能允许在流中准确计时。
  • 它们完全不同。一种是使用主机端
    计时,另一种是使用设备驱动计时。在最简单的情况下,两者测量的时间将具有可比性。但是,在主机端计时版本中,如果您将占用大量时间的主机 CPU 操作放在主机计时部分,则当 GPU 操作花费的时间少于主机时,您的时间测量将不会反射(reflect)使用的 GPU 时间操作。
  • 关于cudaEventSynchronize 与 cudaDeviceSynchronize,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47168542/

    相关文章:

    c - CUDA 中流的非阻塞同步?

    cuda for循环疑惑

    c++ - 部分卡片上的 cuda 应用程序

    python - Cuda:未找到库 nvvm

    memory - CUDA 表面与纹理

    cuda - cuda中的矩阵乘法