一机多卡时,主机线程的管理问题

小弟编程新手,正在尝试把两片GPU装在同一机器上实现并行,但是每个GPU都需要由一个不同的CPU线程来控制,不知道该用怎样的算法实现主机线程管理,跪求高手指点!

不断的用cudaSetDevice函数切换就可以了
cudaSetDevice(0);
kernel_on_dev0…
cudaSetDevice(1);
kernel_on_dev1…

哦…两片GPU不能同时工作吗?这样是不是这种双卡并行的意义不是很大

可以的,你需要分别给不同的卡分配任务.

额……用不同的kernel函数?那调用的时候不同的kernel不是一样要分开调用么?这样不就等于是两个GPU运行有先后顺序?

kernel调用默认就是非阻塞的。所以上面tianyuan的代码中不同kernel会在两个GPU上同时执行。

值得提到,这种方式下必须保证所有cuda调用都是非阻塞的,因此内存拷贝需要使用非阻塞版本:cudaMemcpyAsync.

或者如果想舒服点,可以创建2个host thread(例如:CreateThread). 然后在每个线程里面,分别cudaSetDevice(0)或者(1)。然后每个线程该干嘛就干嘛即可。

这个是常用做法,比较简单。

多谢指点,也就是说调用kernel函数的时候,两个GPU都在运行该函数是吧,那还需要cudaSetDevice()吗?

恩,我在书上找到的也是这个办法,但是我对创建thread完全不了解,有没有这个函数相关的资料啥的?多谢了

6#是对2#说法的肯定和补充,so ,LZ你懂得。

祝您编码愉快。

这个函数是win32 api里面的(x64也可用), 这个函数的相关资料位于微软MSDN的:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453(v=vs.85).aspx

在您建立了2个主机线程之后,里面可以分别cudaSetDevice, 启动kernel, 分别等待,等等,每个线程都是常规用法,无需考虑异步调用还是同步的。

这样编写起来符合普通习惯。比较方便。

多谢大神指点,我要找的应该就是这个方法:lol

如果不用cudaSetDevice()对运行Kernel的设备进行设定,它会默认用Device0。不会两个设备都运行同一个Kernel。
所以想要两个设备都运行同一个Kernel也是需要用到cudaSetDevice的。
具体你可以参考CUDA C Programming guide 中Multi-Device System一节,里面有对你所提及情况的详尽解决方案。

其中一个例子:
size_t size = 1024 * sizeof(float);
cudaSetDevice(0); // Set device 0 as current
float* p0;
cudaMalloc(&p0, size); // Allocate memory on device 0
MyKernel<<<1000, 128>>>(p0); // Launch kernel on device 0
cudaSetDevice(1); // Set device 1 as current
float* p1;
cudaMalloc(&p1, size); // Allocate memory on device 1
MyKernel<<<1000, 128>>>(p1); // Launch kernel on device 1