小弟编程新手,正在尝试把两片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