- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
Win10 x64、CUDA 8.0、VS2015、6 核 CPU(12 个逻辑核心)、2 个 GTX580 GPU。
一般来说,我正在开发一个多线程应用程序,它启动与 2 个可用 GPU 关联的 2 个线程,这些线程存储在线程池中。
每个线程在启动时执行以下初始化过程(即,这仅在每个线程运行时完成):
::cudaSetDevice(0 or 1, as we have only two GPUs);
::cudaDeviceSetCacheConfig(cudaFuncCachePreferL1);
::cudaSetDeviceFlags(cudaDeviceMapHost | cudaDeviceScheduleBlockingSync);
然后,从其他工作线程(另外 12 个完全不接触 GPU 的线程),我开始为这 2 个与 GPU 相关的工作线程提供数据,只要启动的 GPU 线程数量相等,它就可以完美运行到可用物理 GPU 的数量。
现在我想启动 4 个 GPU 线程(即每个 GPU 2 个线程)并使每个线程通过单独的 CUDA 流工作。我知道正确使用 CUDA 流所必需的要求,我满足了所有这些要求。我失败的是上面提到的初始化过程。
一旦尝试从不同的 GPU 线程但针对同一 GPU 执行此过程两次,::cudaSetDeviceFlags(...) 开始失败并显示 “无法设置设备在此过程中处于事件状态” 错误信息。
我查看了手册,似乎明白了发生这种情况的原因,我不明白的是如何正确使用::cudaSetDeviceFlags(...) 进行设置。
我可以评论这条::cudaSetDeviceFlags(...) 行,即使每个 GPU 有 8 个线程,propgram 也能正常工作,但我需要设置 cudaDeviceMapHost 标志才能使用流,固定内存不会否则可用。
编辑要考虑#1 的额外信息:
最佳答案
好吧,像往常一样,高度复杂的 trythis-trythat-seewhathappens-tryagain 练习方法终于奏效了。
这是::cudaSetDeviceFlags() 文档的摘录:
Records flags as the flags to use when initializing the current device. If no device has been made current to the calling thread, then flags will be applied to the initialization of any device initialized by the calling host thread, unless that device has had its initialization flags set explicitly by this or any host thread.
因此,在 GPU 工作线程中,有必要在 ::cudaSetDevice() 之前调用::cudaSetDeviceFlags()。
我在 GPU 线程初始化代码中实现了类似这样的东西,以确保在设备集实际应用之前设置的设备标志:
bse__throw_CUDAHOST_FAILED(::cudaSetDeviceFlags(nFlagsOfDesire));
bse__throw_CUDAHOST_FAILED(::cudaSetDevice(nDevice));
unsigned int nDeviceFlagsActual = 0;
bse__throw_CUDAHOST_FAILED(::cudaGetDeviceFlags(&nDeviceFlagsActual));
bse__throw_IF(nFlagsOfDesire != nDeviceFlagsActual);
此外,talonmies 的评论显示了解决::cudaHostUnregister 错误的方法。
关于c++ - 使用 cudaSetDeviceFlags 的正确位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47175958/
Win10 x64、CUDA 8.0、VS2015、6 核 CPU(12 个逻辑核心)、2 个 GTX580 GPU。 一般来说,我正在开发一个多线程应用程序,它启动与 2 个可用 GPU 关联的 2
我是一名优秀的程序员,十分优秀!