【问题标题】:CUDA streams and contextCUDA 流和上下文
【发布时间】:2011-10-12 19:41:24
【问题描述】:

我目前正在使用一个应用程序,它产生一堆 pthreads (linux),每个线程都创建它自己的 CUDA 上下文。 (现在使用 cuda 3.2)。

我遇到的问题是,似乎每个线程都有自己的上下文会在 GPU 上消耗大量内存。每个线程大约 200MB,所以这真的限制了我。

我可以简单地在主机线程中创建流,将流引用传递给工作线程,然后它们就可以将它们的流编号传递给我的 CUDA 库,并且所有工作都在同一个上下文中工作吗?

工作线程是否自动知道与其父线程相同的 CUDA 上下文?

谢谢

【问题讨论】:

    标签: c++ cuda cuda-context


    【解决方案1】:

    每个 CUDA 上下文确实会占用相当多的设备内存,并且它们的资源彼此严格划分。例如,上下文 A 中分配的设备内存不能被上下文 B 访问。流也仅在创建它们的上下文中有效。

    最佳做法是为每个设备创建一个 CUDA 上下文。默认情况下,该 CUDA 上下文只能从创建它的 CPU 线程访问。如果要从其他线程访问 CUDA 上下文,请调用 cuCtxPopCurrent() 从创建它的线程中弹出它。然后可以将上下文推送到任何其他 CPU 线程的当前上下文堆栈,随后的 CUDA 调用将引用该上下文。

    上下文推送/弹出是轻量级操作,从 CUDA 3.2 开始,它们可以在 CUDA 运行时应用程序中完成。所以我的建议是初始化 CUDA 上下文,然后调用 cuCtxPopCurrent() 使上下文“浮动”,除非某些线程想要操作它。将“浮动”状态视为自然状态 - 每当线程想要操作上下文时,将其用法与 cuCtxPushCurrent()/cuCtxPopCurrent() 括起来。

    【讨论】:

    • 是否 PopCurrent() 实际上将其从保存上下文的“队列”中删除,以便其他线程无法访问它?我可以从主机线程中弹出当前上下文,然后将该上下文传递给工作线程,然后将其“推送”到上下文堆栈中吗?听起来上下文必须在“并发队列”中并且有一个互斥体,对吧?
    • 创建上下文时,会将其推送到当前上下文堆栈中。弹出上下文会导致它对任何 CPU 线程都不可用,直到它被 cuCtxPushCurrent() 推送到另一个当前上下文堆栈。因此,您描述的工作流程正是 API 旨在实现的。上下文是线程安全的,因此您需要实现的唯一额外线程同步是根据应用程序的需要强制执行排序或其他语义。
    • 我为每个线程使用cuCtxSetCurrent ( CUcontext ctx )。当线程不再需要上下文时,这是否需要一些东西来释放它,类似于推送后的弹出?
    • 第一次实现 push/pop 时,一次只有一个 CPU 线程可以拥有当前上下文。 cuCtxSetCurrent() 是后来添加的,在 NVIDIA 修复了 CUDA 之后,因此一个上下文可以同时存在多个线程。所以,我希望你的代码能正常工作。
    猜你喜欢
    • 1970-01-01
    • 2017-08-31
    • 2022-11-10
    • 2013-07-17
    • 1970-01-01
    • 2013-06-03
    • 1970-01-01
    • 2018-05-07
    • 2019-10-13
    相关资源
    最近更新 更多