cudaEventSynchronize vs cudaDeviceSynchronize

cudaEventSynchronize vs cudaDeviceSynchronize,cuda,cuda-events,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新手,对
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)
,我们是否需要再次调用
cudaevicesynchronize

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;
#包括
自动tic=std::chrono::system_clock::now();
//内核函数在这里。。。
CUDA_ERR_CHECK(cudaDeviceSynchronize());
自动时钟=标准::时钟::系统时钟:现在();
float elapsedTime=std::chrono::duration\u cast(toc-tic).count()*1.0;

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

  • 否,不需要调用
    cudaDeviceSynchronize()
    。事实上,在多个流中使用异步API调用的许多情况下,使用全局作用域同步调用是不正确的,因为您将破坏事件计时器的功能,这些功能允许对流中的操作进行精确计时

  • 他们完全不同。一种是使用主机端 定时,另一种是使用设备驱动程序定时。在最简单的情况下,两者测量的时间是可比较的。但是,在主机端定时版本中,如果将占用大量时间的主机CPU操作放在主机定时部分,则当GPU操作占用的时间少于主机操作时,时间度量将不会反映所使用的GPU时间


  • 1.没有必要。一种是使用基于cudaEvent的计时,另一种是使用基于CPU的计时。基于CPU的计时可能包括不在基于cudaEvent的计时中的开销和延迟,但这些差异通常很小或无关紧要。@RobertCrovella感谢您的回答。cudaEventSynchronize到底在做什么?文件上写着“等待事件(停止)完成”。我可以看到内核是并行执行的,但是它们每个都有一个“停止”吗?或者它在测量“停止”之前等待所有并行内核执行完成?