重复使用CUDA中的事件变量是否值得?

3

在使用CUDA中的事件时,我通常会创建一个事件,并立即在某个流上记录它。在同步之后,我不必把那个cudaEvent_t保留下来,在其他地方使用它 - 我只是销毁它。

除了避免事件创建和销毁的开销外,有没有"回收"事件的其他好处?如果没有,为什么nVIDIA要将cudaEventCreate()cudaEventRecord()分开?


是的。一个独立的create()看起来是避免创建开销的直接方法。为什么你认为nVidia仍然需要“其他好处”来做出这个设计决策? - kangshiyin
1
我相信事件创建是一项同步活动。我相当确定事件记录不是。在管道/处理循环中,为了避免设备范围内的同步活动,最好像在性能敏感的处理循环中不会(也不应该)肆意使用cudaMalloc/cudaFree一样。 - Robert Crovella
@kangshiyin:因为事件似乎除了记录之外,没有任何用处或产生额外开销。 - einpoklum
@RobertCrovella:这对我来说有点奇怪——我的意思是,当你使用malloc时,你会给出一个参数——大小;这需要更新一些主机端和可能的设备端数据结构。但是说“嘿,事件!”不应该真正做任何事情。最多你会认为你会有像cudaSetMaxConcurrentEvents()这样的东西,你只需要运行一次。无论如何,也许这应该是一个答案。 - einpoklum
我并不完全确定cudaEventCreate的同步行为,因为它的文档说明并不清晰。不过,构建一个有向测试来证明或证伪应该很容易。1. 如果文档没有明确说明,当你怀疑时,cuda API调用可能会进行同步。2.cudaEventRecord明确表示它是异步的。3. 我不明白两个进程如何都可以是异步的——事件本身只是一个句柄,但创建过程会更新一个CUDA运行时必须能够引用的表(甚至在其他设备上!)。无论如何,我可能是错的,测试和证明/证伪应该很容易。 - Robert Crovella
显示剩余2条评论
1个回答

3

首先,我试图回答“开销可能是什么”的问题。由于我们没有CUDA事件的源代码,所以所有推测都是合理的。你可以基于相同或类似行为做出完全不同的设计决策来实现CUDA事件。

在计时任务中,我们知道至少事件的时间在某个地方被记录下来。由于事件发生在设备端,我认为为了避免在记录期间使用PCIe(高开销),时间会被记录在设备端内存中。最终你从主机端获取时间时,记录下的时间必须在某个时候通过PCIe传输(可能是eventSync())。

你可以看到,在整个过程中,你需要一些空间来存储时间,包括主机和设备端内存。像malloc()/free()一样,在eventCreate()/eventDestroy()中分配/释放内存看起来很好。这也看起来是一个完美的开销,你希望在重复记录时间时(重用事件)避免它。

因此,这里有两种开销:分配设备和主机空间,以及PCIe传输。这是我的猜测。也许你可以通过另一种方式来实现计时功能,而不涉及这些开销。

最后,避免这些开销似乎是nVidia使用单独的eventCreate()的一个好理由。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接