C++ CUDA 5.0多GPU环境下的单应用程序线程上下文管理
似乎大多数教程、指南、书籍和网上问答都提到了CUDA3和4.x,所以我特别问CUDA5.0。关于这个问题 我想为一个有两个CUDA设备的环境编程,但只使用一个线程,以简化设计(特别是因为它是一个原型)。我想知道以下代码是否有效:C++ CUDA 5.0多GPU环境下的单应用程序线程上下文管理,c++,memory-management,cuda,multiple-gpu,cuda-context,C++,Memory Management,Cuda,Multiple Gpu,Cuda Context,似乎大多数教程、指南、书籍和网上问答都提到了CUDA3和4.x,所以我特别问CUDA5.0。关于这个问题 我想为一个有两个CUDA设备的环境编程,但只使用一个线程,以简化设计(特别是因为它是一个原型)。我想知道以下代码是否有效: float *x[2]; float *dev_x[2]; for(int d = 0; d < 2; d++) { cudaSetDevice(d); cudaMalloc(&dev_x[d], 1024); } for(int re
float *x[2];
float *dev_x[2];
for(int d = 0; d < 2; d++) {
cudaSetDevice(d);
cudaMalloc(&dev_x[d], 1024);
}
for(int repeats = 0; repeats < 100; repeats++) {
for(int d = 0; d < 2; d++) {
cudaSetDevice(d);
cudaMemcpy(dev_x[d],x[d],1024,cudaMemcpyHostToDevice);
some_kernel<<<...>>>(dev_x[d]);
cudaMemcpy(x[d],dev_x[d],1024,cudaMemcpyDeviceToHost);
}
cudaStreamSynchronize(0);
}
float*x[2];
浮动*dev_x[2];
对于(int d=0;d<2;d++){
cudaSetDevice(d);
库达马洛克(&dev_x[d],1024);
}
for(int repeats=0;repeats<100;repeats++){
对于(int d=0;d<2;d++){
cudaSetDevice(d);
cudaMemcpy(dev_x[d],x[d],1024,cudamemcpyhostodevice);
一些内核(dev_x[d]);
cudaMemcpy(x[d],dev_x[d],1024,cudaMemcpyDeviceToHost);
}
cudaStreamSynchronize(0);
}
我特别想知道,即使在同一线程中发生了cudaSetDevice()
的交换,测试之前的cudamaloc(…)
s是否仍然存在。另外,我想知道上下文相关对象(如cudaEvent\u t
和cudaStream\u t
)是否也会发生同样的情况
我这样问是因为我有一个这种风格的应用程序,它不断地出现一些映射错误,如果缺少内存泄漏或API使用错误,我无法找到它是什么
注意:在我的原始代码中,我会检查每个CUDA调用。我把它放在这里不是为了代码可读性。这只是一个打字错误吗
for(int d = 0; d < 2; d++) {
cudaSetDevice(0); // shouldn't that be 'd'
cudaMalloc(&dev_x, 1024);
}
for(int d=0;d<2;d++){
cudaSetDevice(0);//不应该是“d”吗
库达马洛克(和德夫x,1024);
}
请检查所有API调用的返回值 是的,应该可以。Cudamaloc、streams和events分配的区域都特定于创建它们的设备(最近的
cudaSetDevice()
call)。因此,您应该确保只使用与正在访问的设备相关的项目。其他信息。另外,x[d]
由于它位于主机上,除非您愿意,否则不需要为每个设备编制索引。这是否适用于与上下文相关的对象,如流和事件?如果不是打字错误,并且所有API调用都返回成功,然后,您问题中的信息似乎不足以识别您的问题,因为它看起来正常(尽管有不必要的cudaStreamSynchronize()
)。你能试着制作一个复制品吗?您也可以尝试使用cuda memcheck运行以查找OOB错误和泄漏(使用leakcheck选项)。您不必调用cudaStreamSynchronize(),因为cudaMemcpy()调用是同步的。另外,请注意,在循环终止后,设备1将是CPU线程的当前设备。