等待后续流中的事件

时间:2014-11-26 10:05:50

标签: cuda cuda-events

我正在尝试使用CUDA在GPU上实现以下类型的管道:

Pipeline

我有四个流,每个流都有一个Host2Device副本,一个内核调用和一个Device2Host副本。但是,内核调用必须等待下一个流的Host2Device副本完成。

我打算使用cudaStreamWaitEvent进行同步。但是,根据文档,这仅适用于之前为相应事件调用cudaEventRecord的情况。在这种情况下情况并非如此。

流由不同的CPU线程管理,基本上如下所示:

Do some work ...
cudaMemcpyAsync H2D
cudaEventRecord (event_copy_complete[current_stream])
cudaStreamWaitEvent (event_copy_complete[next_stream])
call kernel on current stream
cudaMemcpyAsync D2H
Do some work ...

管理CPU线程以正确的顺序启动流。因此,在该事件的cudaStreamWaitEvent之前(在流1中)调用流{1的复制完成事件的cudaEventRecord(在流0中)。这导致功能无操作。

我觉得事件不能以这种方式使用。还有另一种方法可以实现所需的同步吗?

顺便说一下,我不能只是反转流顺序,因为还有一些依赖项。

API电话订单

根据要求,以下是发出CUDA呼叫的顺序:

//all on stream 0
cpy H2D
cudaEventRecord (event_copy_complete[0])
cudaStreamWaitEvent (event_copy_complete[1])
K<<< >>>    
cpy D2H

//all on stream 1
cpy H2D
cudaEventRecord (event_copy_complete[1])
cudaStreamWaitEvent (event_copy_complete[2])
K<<< >>>    
cpy D2H

//all on stream 2
cpy H2D
cudaEventRecord (event_copy_complete[2])
cudaStreamWaitEvent (event_copy_complete[3])
K<<< >>>    
cpy D2H
...

可以看出,对cudaStreamWaitEvent的调用总是早于对cudaEventRecord的调用。

1 个答案:

答案 0 :(得分:1)

如果可能,您应该从单个CPU线程调度所有这些GPU工作。这样,(存在明显陈述的风险),API调用的执行顺序可以从它们在代码中出现的顺序推断出来。由于cudaEventRecord()cudaStreamWaitEvent()调用都对与CUDA上下文关联的进度值进行操作,因此API调用的确切顺序非常重要。 cudaEventRecord()记录当前进度值,然后递增它; cudaStreamWaitEvent()发出当前GPU等待事件当前进度值的命令。 (这就是为什么如果你颠倒调用的顺序,等待就变成了有效的无操作。)

如果API调用是从不同的线程进行的,则必须进行大量的线程同步才能生成所需的结果,这也会对性能产生负面影响。实际上,如果出于性能原因需要多个CPU线程,您可能需要重新构建代码以将CUDA调用委托给单个CPU线程以强制执行排序。