确定cuda设备是否正在使用?

确定cuda设备是否正在使用?,cuda,cupy,Cuda,Cupy,有没有办法直接测试cuda设备当前是否被任何内核使用? 我有一个后台线程,在分形程序的完全占用情况下启动“原始”cuda内核。该线程建立了大型图像阵列,然后我想让用户平滑地平移、旋转和缩放 如果GPU当前未用于大型图像转换,我的GUI线程希望使用GPU,因为它以100fps的速度运行。如果GPU正在使用,我可以退回到使用CPU代码,而不是以10-20 fps的速度 如果在后台线程内核已经运行时使用GUI线程GPU代码,那么GUI线程将明显冻结,直到后台内核完成。我正试图通过切换到这些帧的CPU代

有没有办法直接测试cuda设备当前是否被任何内核使用?

我有一个后台线程,在分形程序的完全占用情况下启动“原始”cuda内核。该线程建立了大型图像阵列,然后我想让用户平滑地平移、旋转和缩放

如果GPU当前未用于大型图像转换,我的GUI线程希望使用GPU,因为它以100fps的速度运行。如果GPU正在使用,我可以退回到使用CPU代码,而不是以10-20 fps的速度

如果在后台线程内核已经运行时使用GUI线程GPU代码,那么GUI线程将明显冻结,直到后台内核完成。我正试图通过切换到这些帧的CPU代码来消除这种冻结。我已经研究过中断后台内核,但我看到的解决方案是,这样做会增加内核的计算成本和/或重置上下文,这两种方法看起来都有些过分

有没有一种方法可以直接(异步)检测GPU是否正在(由任何内核)使用?我想GPU在技术上一直被用作二维显示驱动程序,所以当然排除了这种活动

我的解决方法是在我的程序中有一个标记,它跟踪是否所有内核都已完成。我需要在两个主机线程之间以及程序中模型和视图中嵌套最多的对象之间传递该标志。我开始写这篇文章,认为这是一个有点混乱的解决方案,即使这样也不总是100%准确。因此,我想知道是否有更好的方法,特别是是否可以在GUI线程中需要决定是否在下一帧使用GPU或CPU代码的位置直接测试GPU

我使用Python 3.7,用CUPY访问GPU,但是我愿意尝试适应C++解决方案。 我已经查阅了文档,但仅凭cuda的基本知识,感觉就像大海捞针一样:


这是我在@RobertCrovella的帮助下使用的解决方案

import cupy as cp

stream_done: bool = cp.cuda.get_current_stream().done

if stream_done or worker_ready:
    # use cupy to draw next frame
else:
    # use numpy to draw next frame
其中worker_ready是从后台worker GPU线程传递的bool,表示其活动

有关完成的流,请参阅。在我的程序中,我只使用1个cuda流,即(未指定的)默认流。否则,我想您需要根据问题测试每个流

经过大量测试,我发现:

cp.cuda.get_current_stream().done
在内核运行后立即在后台线程中为True,但在需要执行测试的地方可能会变为False,尽管我的代码没有在True和False状态之间调用GPU。我无法解释这种行为,但我发现我不能仅仅依靠stream_done。我的测试表明:如果stream_done在要求的点上是真的,那么使用GPU总是安全的;如果stream_done为False,则使用GPU可能安全,也可能不安全

我还让后台线程在启动和停止时触发一个事件,该事件会更改GUI线程的worker_ready bool。我的测试表明worker_ready在确定是否可以使用GPU方面比stream_更准确。在stream_done为True而worker_ready为False的情况下,我的测试显示GPU代码也会快速运行,可能是因为后台线程在该时间点执行CPU代码

所以,正如我所说的,解决这个问题的最好办法是在满足任何一个条件的情况下使用GPU代码。然而,即使这样也没有消除我试图消除的视觉滞后

我试图解决的问题是,当一个后台进程在GPU上运行,用户尝试平移时,偶尔会出现至少0.5s的明显滞后。我试图通过测量从按下鼠标到显示平移图像的时间来量化这种延迟。测量的时间延迟为0.1s或更小。因此,无论鼠标点击后代码的速度有多快,无论是使用GPU还是CPU,都无法消除延迟。 对我来说,这意味着启动鼠标按下事件本身在GPU被占用时触发延迟。这大概是因为GPU也在运行显示驱动程序。除此之外,我没有任何确凿的证据:

  • 如果后台线程没有运行,那么延迟将被删除
  • 缩短核的数量级并不能减少延迟
  • 增加街区面积,使其远离全住区,似乎在大多数情况下都能消除这种滞后现象,尽管这并不能完全消除这种现象

通过对cuda数据流使用的一些管理,您可以使用。A建议
done
属性是如何在
cupy
中实现的,但我没有一个完整的解决方案。此外,我觉得有必要指出,如果您在完全异步的wild west环境中运行,您有独立的异步工作提交者,您可以对GPU的状态进行采样,发现它是空闲的,然后一纳秒后另一个工作提交者可以提交一些东西到GPU。所以我怀疑这种异步采样方法是否是一种可靠的技术。@RobertCrovella第一个建议看起来很有希望。我稍后会尝试并再次发表评论。我只使用默认的steam,所以应该足够简单。关于第二个建议,您是说为纳秒内核启动一个新的python线程吗?然后,如果内核在短时间内成功运行,该线程是否会发出一个事件,将主线程中的gpu可用标志更新为True?纳秒级内核,即使在一个单独的流中运行,如果GPU被占用,当然也不会运行,因为我的主内核是在完全占用的情况下运行的。即使后台内核正在运行,您也可以使用流优先级让GUI内核正常工作,但这可能取决于一些内核配置