【发布时间】:2020-12-29 23:19:51
【问题描述】:
有没有办法直接测试 cuda 设备当前是否被任何内核使用?
我有一个后台线程,它为分形程序在完全占用的情况下启动“原始”cuda 内核。该线程构建了大型图像数组,然后我想让用户平滑地平移、旋转和缩放。
如果 GPU 目前没有用于大图像转换,我的 GUI 线程想使用它,因为它以 100 fps 运行。如果 GPU 正在使用中,我可以回退到使用 CPU 代码,而不是 10-20 fps。
如果在后台线程内核已经运行时使用 GUI 线程 GPU 代码,则 GUI 线程将明显冻结,直到后台内核完成。这种冻结是我试图通过切换到这些帧的 CPU 代码来消除的。我已经研究过中断后台内核,但我看到的解决方案会增加内核的计算成本和/或重置上下文,这两者似乎都过大了。
有没有办法直接(异步)检测 GPU 是否正在使用(任何内核)?我想 GPU 在技术上总是被用作 2-D 显示驱动程序,因此当然不包括该活动。
我的解决方法是在我的程序中设置一个标志来跟踪是否所有内核都已完成。我需要在两个主机线程之间以及程序中模型和视图中最嵌套的对象之间传递该标志。我开始写这篇文章并认为这是一个有点混乱的解决方案,即使这样也并不总是 100% 准确。所以我想知道是否有更好的方法,特别是是否可以在 GUI 线程中直接测试 GPU,从而决定下一帧是使用 GPU 还是 CPU 代码。
我正在使用 python 3.7,通过 cupy 访问 GPU,但我愿意尝试采用 C++ 解决方案。
我查看了文档,但只有 cuda 的基本知识,感觉就像大海捞针: https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__DEVICE.html#group__CUDART__DEVICE
【问题讨论】:
-
通过对 cuda 流的使用进行一些管理,您也许可以使用
cudaStreamQuery()。 casual glance 表明done属性是在cupy中实现的方式,但我没有完整的解决方案。 -
另外,我不得不指出,如果您在完全异步的狂野西部环境中运行,您有独立的异步工作提交者,您可以对 GPU 的状态进行采样,发现它是空闲,然后一纳秒后,另一个工作提交者可以向该 GPU 提交一些东西。所以我怀疑这种异步采样方法是一种强大的技术。
-
@RobertCrovella 第一个建议看起来很有希望。我会尝试一下,稍后再发表评论。我只使用默认的蒸汽,所以应该很简单。
-
第二个建议,你是说为纳秒内核启动一个新的python线程吗?如果内核在短时间内成功运行,那么该线程是否会在主线程中发出将 gpu_available 标志更新为 True 的事件?纳秒内核,即使在单独的流中运行,如果 GPU 被占用,当然也不会运行,因为我的主内核正在满载运行。
-
即使后台内核正在运行,您也可以使用流优先级让 GUI 内核正常工作,但这可能取决于许多不可能的内核特性从你的问题中推断出来,这似乎没有暴露在cupy中。另一种方法是对工作提交进行一些控制。创建一个包装工作提交函数,1.获取全局锁 2.启动工作 3.启动回调释放全局锁。如果您可以从 GUI 线程获取全局锁,请在此处启动。否则,使用 CPU。