多个GPU上的CUDA上下文、流和事件
TL;DR version:“使用Python/PyCUDA对多个GPU进行循环内核调用,从而使CPU和GPU并行工作的最佳方式是什么?”带有“我不可能是第一个问这个问题的人;有什么我应该读的吗?” 完整版本: 我想知道在具有多个GPU的系统上使用CUDA的应用程序中设计上下文等处理的最佳方法。我一直在努力寻找文献,其中讨论了上下文重用与娱乐何时合适的指导原则,但到目前为止还没有找到任何概述最佳实践、经验法则等的内容 我们需要做的总体概述如下:多个GPU上的CUDA上下文、流和事件,cuda,pycuda,Cuda,Pycuda,TL;DR version:“使用Python/PyCUDA对多个GPU进行循环内核调用,从而使CPU和GPU并行工作的最佳方式是什么?”带有“我不可能是第一个问这个问题的人;有什么我应该读的吗?” 完整版本: 我想知道在具有多个GPU的系统上使用CUDA的应用程序中设计上下文等处理的最佳方法。我一直在努力寻找文献,其中讨论了上下文重用与娱乐何时合适的指导原则,但到目前为止还没有找到任何概述最佳实践、经验法则等的内容 我们需要做的总体概述如下: 请求进入一个中心进程 该过程分叉处理单个请求 数
- 请求进入一个中心进程
- 该过程分叉处理单个请求
- 数据从数据库加载(相对昂贵)
- 几个快速的内核调用来计算后续内核所需的数据
- 一次缓慢的内核调用(10秒)
- 内核调用的结果在CPU上收集和处理,然后存储
- 在开始任何GPU工作之前创建上下文
- 为第一组数据启动内核
- 在系列中的最后一个内核调用之后为录制事件
- 当第一组数据在GPU上计算时,在CPU上准备第二组数据
- 启动第二组,重复
- 在收集和存储结果之前,确保每个事件都已同步
请注意,以链接的形式回答我的问题的其他内容是完全可以接受的(甚至是鼓励的),前提是这些内容足够详细地说明了为什么,而不仅仅是API。谢谢你的阅读 警告:我还不是PyCUDA用户 使用CUDA 4.0+时,每个GPU甚至不需要显式上下文。您只需调用
cudaSetDevice
(或PyCUDA等效程序),然后再进行每设备操作(cudamaloc
、cudaMemcpy
、启动内核等)
如果需要在GPU之间进行同步,则可能需要创建流和/或事件,并使用cudaEventSynchronize
(或PyCUDA等效工具)。您甚至可以让一个流等待插入到另一个流中的事件,以执行复杂的依赖关系
所以我怀疑今天的答案比泰龙的优秀答案要简单得多
你可能也会发现这很有用
(Re)按OP编辑:据我所知,PyCUDA支持4.0之前的CUDA版本,因此仍然使用旧的API/语义(驱动程序API?),因此Talonmes的答案仍然相关。警告:我不是PyCUDA用户(目前) 使用CUDA 4.0+时,每个GPU甚至不需要显式上下文。您只需调用
cudaSetDevice
(或PyCUDA等效程序),然后再进行每设备操作(cudamaloc
、cudaMemcpy
、启动内核等)
如果需要在GPU之间进行同步,则可能需要创建流和/或事件,并使用cudaEventSynchronize
(或PyCUDA等效工具)。您甚至可以让一个流等待插入到另一个流中的事件,以执行复杂的依赖关系
所以我怀疑今天的答案比泰龙的优秀答案要简单得多
你可能也会发现这很有用
(Re)按OP编辑:据我所知,PyCUDA支持4.0之前的CUDA版本,因此仍然使用旧的API/语义(驱动程序API?),因此Talonmes的答案仍然是相关的。Uhrm,“用Python/PyCUDA循环多个GPU的内核调用以使CPU和GPU并行工作的最佳方式是什么?”“我不可能是第一个问这个问题的人;有什么我应该读的吗?“与之类似,但它早于CUDA 4.0版本,该版本对多gpu进行了很多更改。我希望避免每个内核调用上下文,但这可能是不现实的。您不需要每个内核调用上下文,您需要每个gpu上下文。理想的持久性。这曾经意味着每个设备一个线程。从CUDA 4.0开始,它就没有了。你可以用一根线。我经常使用pycuda,但通常使用mpi4py,因为我主要使用集群。我还没有用CUDA4.Uhrm尝试过CUDA4.0风格的多GPU,“对多个GPU进行循环内核调用的最佳方法是什么