cuDevicePrimaryCtxRetain() 是不是用于在多个进程之间拥有持久的 CUDA 上下文对象?

Posted

技术标签:

【中文标题】cuDevicePrimaryCtxRetain() 是不是用于在多个进程之间拥有持久的 CUDA 上下文对象?【英文标题】:Is cuDevicePrimaryCtxRetain() used for having persistent CUDA context objects between multiple processes?cuDevicePrimaryCtxRetain() 是否用于在多个进程之间拥有持久的 CUDA 上下文对象? 【发布时间】:2018-07-04 19:22:49 【问题描述】:

仅使用驱动程序 api,例如,我有一个带有单个进程的分析(cuCtxCreate),cuCtxCreate 开销几乎相当于 300MB 数据复制到/从 GPU:

在 CUDA 文档 here 中,它说(对于 cuDevicePrimaryCtxRetain)Retains the primary context on the device, creating it **if necessary**。这是从命令行重复调用同一进程的预期行为(例如运行 1000 次进程以显式处理 1000 个不同的输入图像)?设备是否需要 CU_COMPUTEMODE_EXCLUSIVE_PROCESS 才能按预期工作(多次调用时重复使用相同的上下文)?

现在,即使我多次调用该过程,上图也是相同的。即使不使用分析器,时间也显示大约 1 秒的完成时间。

编辑:根据文档,主要上下文是one per device per process。这是否意味着在使用多线程单应用程序时不会出现问题?

什么是主要上下文的重用时间限制?进程之间的 1 秒可以吗,还是必须以毫秒为单位才能保持主上下文处于活动状态?

我已经将 ptx 代码缓存到一个文件中,因此唯一剩余的开销看起来像 cuMemAlloc()、malloc() 和 cuMemHostRegister(),因此重新使用上次调用同一进程的最新上下文可以很好地优化时序。

Edit-2: 文档说 The caller must call cuDevicePrimaryCtxRelease() when done using the context. 代表 cuDevicePrimaryCtxRetaincaller 这里有任何进程吗?我可以在数百个顺序调用的进程列表中只在第一个调用的进程中使用保留并在最后一个调用的进程上使用释放吗?如果最后一个进程无法启动并且没有调用cuDevicePrimaryCtxRelease,系统是否需要重置?

Edit-3:

主要上下文是否适用于此?

process-1: retain (creates)
process-2: retain (re-uses)
...
process-99: retain (re-uses)
process-100: 1 x retain and 100 x release (to decrease counter and unload at last)

一切都是为 sm_30 编译的,设备是 Grid K520。 GPU 在 cuCtxCreate() 期间处于提升频率 项目是在 windows server 2016 操作系统和 CUDA 驱动程序安装上编译的 64 位(发布模式)与 windows-7 兼容(这是 K520 + windows_server_2016 的唯一方法)

【问题讨论】:

在任何情况下,驱动程序 API 都不存在“持久”上下文这样的东西,据我所知,您基本上误解了上下文是什么、上下文 API 是什么被设计来做,你应该如何使用它们 我的理解是,给每个GPU一个上下文,它控制着所有的操作,比如内存分配,内核调用,内存拷贝,创建和销毁都需要时间,好像做1000s比较好每个上下文创建-销毁的操作数。我只是问是否可以使用主要上下文来绕过这种创建 - 破坏,所以我不需要为每个进程计算 1000 件事情。 每个 GPU 的每个 进程 都有一个上下文。有很大的不同。 我昨天尝试了主要上下文,它没有改变延迟。启动仍然需要 150 毫秒。 是的,因为主要上下文旨在用于与您想象的完全不同的事物。它旨在允许驱动程序 API 绑定到现有的运行时 API 上下文。仅此而已 【参考方案1】:

tl;dr:不,不是。

cuDevicePrimaryCtxRetain() 是否用于在多个进程之间拥有持久的 CUDA 上下文对象?

没有。它旨在允许驱动程序 API 绑定到使用运行时 API 的库已经延迟创建的上下文。仅此而已。曾几何时,需要使用驱动程序 API 创建上下文,然后将运行时绑定到它们。现在,有了这些 API,您就不必这样做了。例如,您可以在 Tensorflow here 中查看这是如何完成的。

这是否意味着在使用多线程单应用程序时不会出现问题?

从 CUDA 2.0 开始,驱动 API 一直是完全线程安全的

调用者这里有进程吗?我可以在数百个顺序 [原文如此] 调用的进程列表中仅在第一个调用的进程中使用保留并在最后一个调用的进程上使用释放吗?

没有。上下文对于给定的过程总是唯一的。它们不能以这种方式在进程之间共享

主要上下文是否适用于此?

process-1: retain (creates)
process-2: retain (re-uses)
...
process-99: retain (re-uses)
process-100: 1 x retain and 100 x release (to decrease counter and unload at last)

没有。

【讨论】:

以上是关于cuDevicePrimaryCtxRetain() 是不是用于在多个进程之间拥有持久的 CUDA 上下文对象?的主要内容,如果未能解决你的问题,请参考以下文章