我正在尝试配置以下nested thread architecture。
| | |
| | |
||| ||| |||
|vv |vv |vv
v v v
主线程仅在嵌套线程完成后才会继续。
问题在于,在较大的结构中,我可能会遇到饥饿问题,因为嵌套线程会遇到当前使用标准互斥锁循环的自定义锁。在程序加载GPU可以实际同时运行的更多线程之前,这不会成为问题。有没有办法根据互斥逻辑交换活动线程?
答案 0 :(得分:2)
您提供的链接涵盖了CUDA动态并行(CDP)。
在非CDP的情况下,如果您打算使用互斥锁/锁,那么程序员有责任确保所有必要的线程都可以取得进展。没有办法在活动线程之间“交换”。一旦线程由GPU调度程序激活,它必须能够最终取得进展。它将使用调度程序槽(SM上的一个插槽),直到它能够这样做。你无法改变这一点。
CDP案例中有一个例外,它适用于父内核和子内核之间的关系(仅限)。允许父内核启动子内核,如有必要,GPU线程调度程序将“交换”父内核线程,以便子内核线程可以前进,最终满足implicit或{{ 3}}父线程中的同步依赖于子网格的完成。
然而,CDP父/子案例的这种例外并不意味着:
在网格中,无论是父项还是子项,程序员都有责任智能地使用锁或互斥锁,以便网格可以进行必要的前进,而不期望CUDA运行时将交换已分配的线程。 SM上的活动插槽。
也无法明确强制将线程交换进出活动SM插槽。隐式方法是已经讨论过的CDP机制,explicit但是只保证在特定网格中发生线程交换。
(关于流优先级,在它的当前实现中我不相信它会交换当前调度的线程或线程块,直到它们完成。它实际上是机会调度控制,而不是抢先调度控制,它将调度线程块当机会 - SM上的可用调度时隙 - 出现时,来自更高优先级的流。但是,AFAIK,CUDA执行模型中没有任何内容明确地阻止流优先级交换活动线程块,因此行为可能会改变在将来。)