多个进程并行启动 CUDA 内核

Posted

技术标签:

【中文标题】多个进程并行启动 CUDA 内核【英文标题】:Multiple processes launching CUDA kernels in parallel 【发布时间】:2013-01-31 10:44:41 【问题描述】:

我知道具有 2.x 或更高计算能力的 NVIDIA gpus 可以同时执行多达 16 个内核。 但是,我的应用程序产生了 7 个“进程”,这 7 个进程中的每一个都启动 CUDA 内核。

我的第一个问题是这些内核的预期行为是什么。它们是否也会同时执行,或者由于它们是由不同的进程启动的,它们会按顺序执行。

我很困惑,因为 CUDA C 编程指南说:

“来自一个 CUDA 上下文的内核不能与来自另一个 CUDA 上下文的内核同时执行。” 这就引出了我的第二个问题,什么是 CUDA“上下文”?

谢谢!

【问题讨论】:

【参考方案1】:

CUDA 上下文是一个虚拟执行空间,其中包含主机线程或进程拥有的代码和数据。在具有所有当前硬件的 GPU 上,只有一个上下文可以处于活动状态。

所以回答你的第一个问题,如果你有七个独立的线程或进程都试图建立一个上下文并同时在同一个 GPU 上运行,它们将被序列化并且任何等待访问 GPU 的进程都将被阻塞,直到运行上下文的所有者产生。据我所知,没有时间片和调度启发式没有记录,并且(我怀疑)操作系统之间不统一。

您最好启动一个持有 GPU 上下文的工作线程,并使用来自其他线程的消息将工作推送到 GPU。或者,CUDA 驱动程序 API 中提供了一个上下文迁移工具,但它只适用于来自同一进程的线程,并且迁移机制具有延迟和主机 CPU 开销。

【讨论】:

【参考方案2】:

您真的需要单独的线程和上下文吗? 我相信最佳实践是每个 GPU 使用一个上下文,因为单个 GPU 上的多个上下文会带来足够的开销。

要同时执行多个内核,您应该在一个 CUDA 上下文中创建少量 CUDA 流,并将每个内核排队到自己的流中 - 如果有足够的资源,它们将同时执行。

如果您需要从几个 CPU 线程访问上下文 - 您可以使用 cuCtxPopCurrent()、cuCtxPushCurrent() 来传递它们,但任何时候只有一个线程能够使用上下文。

【讨论】:

您能否确认多个上下文可以在单个 GPU 上同时处于活动状态? @Tariq,我没有说明)我可以确认您可以同时在一个 gpu 上运行两个具有两个上下文的程序,但我不知道它们是否都将处于活动状态或司机会以某种方式改变工作流程。 ***.com/questions/31643570/…【参考方案3】:

补充@talonmies的答案

在较新的架构中,通过使用 MPS,多个进程可以同时启动多个内核。所以,现在这绝对是可能的,这在以前是不可能的。如需详细了解,请阅读本文。

https://docs.nvidia.com/deploy/pdf/CUDA_Multi_Process_Service_Overview.pdf

此外,您还可以查看不同 GPU 支持的每种 cuda 计算能力类型允许的最大并发内核数。这是一个链接:

https://en.wikipedia.org/wiki/CUDA#Version_features_and_specifications

例如,cuda 计算能力为 7.5 的 GPU 最多可以启动 128 个 Cuda 内核。

【讨论】:

以上是关于多个进程并行启动 CUDA 内核的主要内容,如果未能解决你的问题,请参考以下文章

内核线程源码分析

内核线程源码分析

多进程概念

Python并发编程—进程

MPI +线程并行化与仅MPI的优势(如果有的话)是什么?

python 并行启动多个子进程并对每个进程进行轮询/等待以确保它完成。最初来自http://stackoverflow.com