CUDA 线程调度:自定义线程 swapping/event 基于锁?

CUDA Thread Scheduling: custom thread swapping/event based locks?

我正在尝试配置以下 nested thread architecture

|   |   |
|   |   |
||| ||| |||
|vv |vv |vv
v   v   v

主线程仅在嵌套线程完成后继续。

问题是,在较大的结构中,我可能 运行 陷入饥饿问题,因为嵌套线程 运行 陷入当前使用标准互斥 while 循环的自定义锁。在程序加载更多 GPU 实际上可以同时 运行 的线程之前,这不会成为问题。有没有一种方法可以根据互斥逻辑在活动线程之间进行交换?

您提供的 link 涵盖了 CUDA 动态并行性 (CDP)。

在非CDP情况下,如果您打算使用mutexes/locks,程序员有责任确保所有必要的线程都能向前推进。活动线程之间无法"swap"。一旦线程被 GPU 调度程序激活,它必须能够最终取得进展。它将消耗一个调度程序槽(SM 上的一个槽)直到它能够这样做。你不能改变这个。

CDP 情况有一个例外,它适用于父内核和子内核之间的关系(仅)。允许父内核启动子内核,GPU 线程调度器将在必要时 "swap" 退出父内核线程,以便子内核线程向前推进,并最终满足 implicit or explicit 同步在依赖于子网格完成的父线程中。

然而,CDP parent/child 案例的例外情况并不意味着:

  1. 父线程将被交换为其他父线程(可能是那些在程序员编写的锁或互斥锁上自旋的线程)
  2. 子线程将被交换为其他子线程

在网格中,无论是父网格还是子网格,程序员都有责任智能地使用锁或互斥锁,以便网格可以取得必要的前进进展,而不是期望 CUDA 运行时会换出已经被删除的线程在 SM 上分配了一个活动槽。

也没有办法显式强制线程交换进出活动的 SM 插槽。隐式方法是已经讨论过的 CDP 机制,CUDA stream priorities 但没有一种方法保证线程交换将在特定网格内发生。

(关于流优先级,在目前的实现中我不相信它会换出当前调度的线程或线程块,直到它们完成。它实际上是一种机会主义的调度控制,而不是抢占式的,它将当机会——SM 上的可用调度槽——出现时,从更高优先级的流中调度线程块。但是,AFAIK,CUDA 执行模型中没有任何内容可以明确阻止流优先级换出活动线程块,因此它可能的行为将来可能会改变。)