此问题与:Does Nvidia Cuda warp Scheduler yield?
有关但是,我的问题是通过执行一些受控的内存操作(强大到足以使线程块产生)来强制线程块产生。我们的想法是允许另一个就绪状态线程块在现在空置的多处理器上执行。
PTX手册v2.3提及(第6.6节):
......大部分内存延迟可以通过多种方式隐藏起来。第一种是拥有多个执行线程,以便硬件可以发出内存操作,然后切换到其他执行。隐藏延迟的另一种方法是尽早发出加载指令,因为在后续(及时)指令中使用所需结果之前不会阻止执行...
所以听起来这可以实现(尽管是一个丑陋的黑客)。有没有人尝试类似的东西?也许用block_size = warp_size设置类型?
编辑:我在没有清楚地理解驻留和非驻留(但分配给相同的SM)线程块之间的区别的情况下提出了这个问题。因此,问题应该是在两个驻留(warp大小)线程块之间切换。道歉!
答案 0 :(得分:2)
在今天的CUDA编程模型中,一旦线程块开始在多处理器上运行,它就会运行完成,占用资源直到它完成。除了从正在执行的全局函数返回之外,线程块无法产生其资源。
多处理器将自动在所有驻留线程块的warp之间切换,因此线程块可以“产生”到其他驻留线程块。但是一个线程块在不退出的情况下不能屈服于非驻留线程块 - 这意味着它无法恢复。
答案 1 :(得分:0)
从计算能力7(Volta)开始,您有了__nanosleep()
指令,它将使线程在给定的纳秒时间内进入睡眠状态。
另一个选项(自计算能力3.5起可用)是使用cudaStreamCreateWithPriority()
调用以较低优先级启动网格。这使您可以以较低的优先级运行一个流。请注意,(某些)GPU仅具有2个优先级,这意味着您可能必须以较高的优先级运行主代码才能躲避默认优先级。
这是一个代码段:
// get the range of stream priorities for this device
int priority_high, priority_low;
cudaDeviceGetStreamPriorityRange(&priority_low, &priority_high);
// create streams with highest and lowest available priorities
cudaStream_t st_high, st_low;
cudaStreamCreateWithPriority(&st_high, cudaStreamNonBlocking, priority_high);
cudaStreamCreateWithPriority(&st_low, cudaStreamNonBlocking, priority_low);