CUDA 定义了一些参数,我不太确定 CUDA 的行为方式,如果我必须尊重它们,或者如果我不尊重它们,它确实会运行,但可能不会获得最佳性能。
查看时cudaGetDeviceProperties
我可以看到一些参数(取自NVidia网站:https ://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__DEVICE.html#group__CUDART__DEVICE_1g1bf9d625a931d657e08db2b4391170f0 :
concurrentKernels
:设备可能可以同时执行多个内核
这只是一个标志还是有任何影响?我认为并发内核只有在使用流时才有意义,对吧?(另请参阅 asyncEngineCount)。
asyncEngineCount
:异步引擎数量
这是上面给出的可以并行运行的内核数量吗?另外,我认为这只在使用流时才有效,对吗?
这让我想到了一个关于流的更普遍的问题。总共可以使用或分配多少个流?例如,如果asyncEngineCount
是 3,那么拥有 3 个以上的流是否有意义?如果我所说的不是真的,那么分配比asyncEngineCount
.
如果我分配的流多于 asyncEngineCount 并让多个内核同时运行,会发生什么情况?假设我分配 10 个流并同时运行 10 个内核,但 asyncEngineCount 只有 3 个。CUDA 是否会一次只运行 3 个内核,而其他内核会被阻塞,直到有一个流空闲为止?
我总是将流解释为一个简单的同步对象,当调用 CUDA 异步方法时,该对象不会发出信号,以便其他方法等待该方法退出并且流设置为有信号,但这似乎是我这边的过于简单的解释?
我找不到关于异步执行和流的很好的解释,也许有更深入的见解。CUDA文档似乎没有解释细节。也许网络或书籍上有很好的解释?
它是一面旗帜,是能力指标。我认为基本上所有 CUDA GPU 都能够运行并发内核。如果有人遇到不具备该功能的 CUDA GPU,我会感到非常惊讶。
是的,要在 CUDA 中安排任何类型的并发(同时发生两个或多个事件),通常需要正确使用流。有一些小的例外,例如主机代码执行和设备代码执行的并发性。
不它不是。
cudaMemcpyAsync
CUDA 中的异步引擎可以被认为是 DMA 引擎,并且每当您发出具有异步运行的实际能力的异步数据传输请求(例如)时都需要/使用它。为了使传输异步发生,使用了硬件引擎,该引擎称为异步引擎。异步引擎对于内核活动没有任何用途或影响,除了使用异步引擎将允许例如数据传输活动在内核执行的同时发生,这取决于各种要求和设备容量。可以创建的流数量没有指定的上限。我见过使用 40 多个流的正确设计的代码。流与
asyncEngineCount
. 如果您创建和使用的流多于设备连接的数量,则流将在设备连接之间分配自身(“别名”),但设备连接也与异步引擎没有明确的关系。不会有什么异常的事情发生。和流之间没有联系
asyncEngineCount
,也没有可以同时执行的内核数量。并发内核执行取决于与 没有连接的因素和资源asyncEngineCount
,并且您当然可以演示不仅仅是asyncEngineCount
并发运行的内核,我上次检查时,concurrentKernels示例代码就是这样做的。并发内核数量存在上限/硬件限制(参见表 18),但与异步引擎无关。对于一般的 CUDA 学习,我通常推荐这个在线培训系列,并且“CUDA 并发”部分有与此主题相关的信息。该编程指南还有关于 CUDA 中的异步并发执行的扩展部分。