我正在多个GPU上实现我的程序...... 我的PC上有两个GPU,想要生成两个独立的流来处理这两个设备。我已经生成了两个流:
cudaStream_t *streams;
streams = (cudaStream_t*) malloc(nstreams * sizeof(cudaStream_t));
for(int j = 0; j < nstreams; j++){
cudaStreamCreate(&(streams[j]));
}
然后我根据SDK示例尝试使用设备ID作为参数调用内核。 根据设备ID,设置cudaDevice(cudaSetDevice(dev_ID);)并且内核调用与各自的流一起传递:
kernel1<<< grid, block,0,streamNo >>>(tex, size);................
for (i = 0;i<gpuN;i++){
initialize(i);
printf("initialization done with stream %i on device %i\n", (int)streams[i], i);
runTest(i);
printf("running tests done with %i stream \n", i);
deini(i);
printf("deinitialization is done\n");
}
我的程序可以正常运行两个不同的流,但它按顺序运行。 我想使用两个设备同时使用两个独立的流来运行函数。任何人都可以帮我解决这个问题吗?
我使用两台特斯拉2070与CUDA 4.2合作。
答案 0 :(得分:2)
您创建的流与您创建它们的上下文相关联,并且在创建它之外的任何上下文中使用流是非法的。在CUDA 4.x及更高版本中,使用cudaSetDevice()
执行上下文切换。
所以为了做到这一点,你需要做类似的事情:
cudaStream_t *streams[ndevices];
for(int i=0; i<ndevices; i++) {
cudaSetDevice(i);
streams[i] = (cudaStream_t*) malloc(nstreams * sizeof(cudaStream_t));
for(int j = 0; j < nstreams; j++){
cudaStreamCreate(&(streams[j]));
}
}
会在枚举nstreams
的每个设备上创建[0,..,ndevices-1]
个流。每当对流执行操作(启动内核,执行异步memcpy等)时,您必须首先执行cudaSetDevice()
到正确的设备上下文。
实际上听起来你可能根本不需要使用流。如果您只有两个流和两个设备,那么主内核启动代码可能非常简单:
for(int i=0; i<2; i++) {
cudaSetDevice(i);
kernel1<<< grid, block >>>(tex, size);
}
根本不需要创建任何流。