求助!python中如何调用cudart64.dll并执行里面的cudaSetDeviceFlags函数?或者有其他方法调用这个函数?

  • 7 replies
  • 1777 views
https://bbs.gpuworld.cn/index.php?topic=58836.0,如这篇文章所说,我想设定BlockingSync的设备标志,来阻塞host线程以获取更高的性能,否则CPU总是处于100%的自旋轮询。但是Pytorch没有这个选项,所以我考虑通过用ctypes调用cudaSetDeviceFlags,但是应该是失败,总之没有效果。pyqt的线程依然是busy polling的状态。这个问题困扰了我很久,有什么解决办法吗?不胜感激!盼回复。

https://bbs.gpuworld.cn/index.php?topic=58836.0,如这篇文章所说,我想设定BlockingSync的设备标志,来阻塞host线程以获取更高的性能,否则CPU总是处于100%的自旋轮询。但是Pytorch没有这个选项,所以我考虑通过用ctypes调用cudaSetDeviceFlags,但是应该是失败,总之没有效果。pyqt的线程依然是busy polling的状态。这个问题困扰了我很久,有什么解决办法吗?不胜感激!盼回复。

我不懂python/pytorch, 但是听你的描述像是在不正确的时机设定了标志(cudaDeviceScheduleBlockingSync需要在最开头就设定好),或者你的时机正确,但是被pytorch内部给重新设定了,这个时候可能并没有什么好的办法。

一个可能的解决方案是,你额外使用ctypes对event对象设定cudaEventBlockingSync, 这个是独立的,而且可以在每次同步都选择不同的方式(例如对预计的短kernel选择spin, 或者普通kernel选择阻塞同步),而且这个可以在任意中途创建event并使用。

也欢迎你给出pytorch的原生解决方案(假设你修改了它的源代码),并发到论坛,方便其他的论坛的兄弟姐妹们。

您好!设定cudaEventBlockingSync标志,这个阻塞host方法粒度更小,应该是更好的选择。但是我尝试过:pytorch封装了Event和Stream对象,但是我尝试了调用,并不能解决,我已在pytorch官网提了issue(详情见:https://github.com/pytorch/pytorch/issues/60541),并没有得到回复。关于ctypes调用cudart64.dll里面的函数,我认为他应该是调用失败了,cudaSetDeviceFlags之后调用cudaGetDeviceFlags返回的结果并不正确。我现在尝试先用C++调用cudaSetDeviceFlags然后重新封装为dll,再到python中调用。然后我还有一个疑问万望解答,pytorch中CPU()方法用于将GPU数据复制回CPU,我不确定他是异步还是同步。如果使用cudaEventSynchronize()应该在CPU()之前还是之后呢。代码可以在issue中看到。感谢您的回复!

所谓的线程busy polling是线程一旦调用设备(GPU)就会busy polling吗,亦或者是GPU触发同步语句包括不限于cudamecpy,才会busy polling?QAQ

所谓的线程busy polling是线程一旦调用设备(GPU)就会busy polling吗,亦或者是GPU触发同步语句包括不限于cudamecpy,才会busy polling?QAQ

你的问题的第一部分,python中的CPU(), 这个我不懂。在最初的时候说过了,欢迎其他使用python/pytorch的用户回答。

关于你的问题的第二部分,何时会spin,根据NV的官方说法:
“当前系统上的CPU核心数量,超过GPU卡的个数的时候,则在CPU<->GPU的时候,会进行忙等“。而没有提到cudaMemcpy()的时候的具体策略。

我建议总是启用使用同步对象的等待(立刻释放时间片)。你可以总是在设备级别或者Event级别启用它。

前辈您好!我的第一个问题是想问我的event的使用是否会和数据传输起到冲突,因为cudamemcpy也存在着隐式同步,我担心它与cudaEventSynchronize()起了冲突。我对event的使用:创建event,指定cudaEventBlockingSync,然后record,最后cudaEventSynchronize(),这个流程应该没有问题吧QAQ,感谢您的回复!

前辈您好!我的第一个问题是想问我的event的使用是否会和数据传输起到冲突,因为cudamemcpy也存在着隐式同步,我担心它与cudaEventSynchronize()起了冲突。我对event的使用:创建event,指定cudaEventBlockingSync,然后record,最后cudaEventSynchronize(),这个流程应该没有问题吧QAQ,感谢您的回复!

我看不懂你的前半部分。。。你可以在一个流里下发cudaMemcpyAsync(),然后后面立刻随着一个event的record(你的后半段),然后等待event的record()在此流中完成。---这是你的意思?

对不起我表述的不是很清楚,就是这个意思QAQ