Runtime API 何时销毁主 CUDA 上下文?

Posted

技术标签:

【中文标题】Runtime API 何时销毁主 CUDA 上下文?【英文标题】:When is a primary CUDA context destroyed by the Runtime API? 【发布时间】:2020-08-14 16:47:45 【问题描述】:

在runtime vs driver API的this discussion中,据说

主上下文根据需要创建,每个设备每个进程一个,被引用计数,然后在没有更多对它们的引用时被销毁。

什么算作这样的引用?而且 - 这是否意味着,通常,主要上下文应该在被重复使用后立即被破坏?例如您获得默认设备 ID,然后启动内核;还剩下什么“参考”?肯定不是保存设备ID的整数变量...

【问题讨论】:

这很有趣,因为在我的一些运行时 API 代码中,当我通过可视化分析器检查它们时,一些代码将显示为每次内核启动都有一个上下文,即使它只是一个带有其他东西的 for 循环。我从来不知道为什么,但是这个问题解释了它:在某些情况下,自动删除/自动创建的上下文是连续的。所以我看到了你提到的效果 在正常情况下,主上下文永远不会被运行时 API 销毁,除非您调用 cudaDeviceReset 或触发 atexit() 路径。 @talonmies:这听起来很合理(尽管“重置”听起来不应该破坏上下文,只是重置它)-但这似乎与引用的段落相矛盾。 不,这并不矛盾。引用计数在驱动程序中,并且惰性上下文建立机制具有“粘性”引用,在您重置或调用 atexit 之前不会被清除 @talonmies:最后一条评论听起来像是答案。 【参考方案1】:

没有记录运行时 API 的确切内部工作原理,并且有经验证据表明它们随着时间的推移发生了微妙的变化。也就是说,如果您检查工具链发出的主机代码样板并运行一些主机端跟踪,则可以推断它是如何工作的,以下是我基于以这种方式进行的观察的理解。

重要的是要认识到主上下文引用计数是驱动程序中的一个内部函数,并且“惰性上下文建立”机制本身使用一些内部 API 挂钩,这些挂钩将绑定到由驱动程序 API 显式创建的现有主上下文(这会增加引用计数)或如果没有可用则自己创建一个,然后绑定到该上下文(这也会增加引用计数)。与主上下文解除绑定的例程通过atexit 注册,并在应用程序退出或调用cudaDeviceReset() 时触发。

这种方法可以防止您假设的潜在情况,即当上下文的引用计数降至零时不断销毁上下文,然后在调用另一个运行时 API 函数时重新创建上下文。这不会发生。

【讨论】:

以上是关于Runtime API 何时销毁主 CUDA 上下文?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我应该使用 CUDA Driver API 而不是 CUDA Runtime API?

深度学习部署(十三): CUDA RunTime API thread_layout线程布局

我应该如何以及何时将倾斜指针与 cuda API 一起使用?

直到啥时候才能设置 CUDA 设备(主上下文)调度策略?

如何将 cuda 驱动程序 api 与 cuda 运行时 api 混合使用?

如何从驱动程序 API 使用运行时 API 创建的上下文