CUDA 代码使两个 GPU “忙”
Posted
技术标签:
【中文标题】CUDA 代码使两个 GPU “忙”【英文标题】:CUDA code makes both GPUs "busy" 【发布时间】:2015-12-11 11:38:03 【问题描述】:我有一台带有 2 个 Nvidia GPU、一个 Tesla 和一个 Gforce 的 PC (Windows 7 x64)。
两者兼有的想法是能够将 Tesla 用于计算,并将 Gforce 用于计算机可能需要的屏幕/openGL 东西。
但是,每当我运行一些 CUDA 代码时,我都无法访问任何具有 webGL 的网络(使用 chrome),因为我的 webGL 是“不可用的”(检查访问 chrome://gpu/)。这仅在运行 CUDA 代码后发生。
我正在使用的代码由 Matlab mex 调用,但不使用任何其他 Matlab 功能,只是 mexErrMsgIdAndTxt
和一些其他 io
代码在 Matlab 和 C 之间包装。
在我的代码中,我有以下代码来选择正确的显卡:
int deviceCount = 0;
cudaGetDeviceCount(&deviceCount);
if (deviceCount == 0)
mexErrMsgIdAndTxt("CBCT:CUDA:Ax:cudaGetDeviceCount","No CUDA enabled NVIDIA GPUs found");
bool found=false;
for (int dev = 0; dev < deviceCount; ++dev)
cudaSetDevice(dev);
cudaDeviceProp deviceProp;
cudaGetDeviceProperties(&deviceProp, dev);
if (strcmp(deviceProp.name, "Tesla K40c") == 0)
found=true;
break;
if (!found)
mexErrMsgIdAndTxt("CBCT:CUDA:Ax:cudaDevice","No Tesla K40c found");
当代码结束时我调用
cudaDeviceReset();
我的印象是(当然是错误的)这段代码可以确保 Gforce 可以免费供 PC 使用,但事实并非如此。
为什么会这样? 我应该在我的代码中添加什么以确保 Gforce 可以免费用于计算机?
【问题讨论】:
【参考方案1】:这不是你应该添加的,而是你应该删除的。不要这样做:
for (int dev = 0; dev < deviceCount; ++dev)
cudaSetDevice(dev);
cudaDeviceProp deviceProp;
cudaGetDeviceProperties(&deviceProp, dev);
if (strcmp(deviceProp.name, "Tesla K40c") == 0)
found=true;
break;
改为这样做:
for (int dev = 0; dev < deviceCount; ++dev)
cudaDeviceProp deviceProp;
cudaGetDeviceProperties(&deviceProp, dev);
if (strcmp(deviceProp.name, "Tesla K40c") == 0)
cudaSetDevice(dev);
found=true;
break;
从 CUDA 4.0 开始,cudaSetDevice()
在设备上建立上下文。因此,仅仅通过寻找正确的 GPU 的行为,您实际上是在初始化一个上下文并使每个设备都忙于 OpenGL。去掉无条件的cudaSetDevice()
,问题就会消失(也不需要cudaDeviceReset()
)。
【讨论】:
确实,就这么简单! 值得注意的是,我从 cudaSamples 中截取了这段代码。他们也应该听从你的建议! 平心而论,cudaDeviceReset
的功能可能随着时间的推移略有变化。文档有点暗示它应该破坏并从设备中弹出上下文,但也许它没有。重要的一点是cudaGetDeviceProperties
不需要(也从来没有)需要上下文才能工作,建立上下文然后尝试销毁它似乎是一个相当糟糕的设计选择,如果你不需要它的替代方案将完全跳过上下文建立。
谢谢!很高兴知道。实际上,在不需要时使用 setDevice() 是一个可怕的设计选择。感谢您的提示;)
您具体指的是哪个 cuda 样本?以上是关于CUDA 代码使两个 GPU “忙”的主要内容,如果未能解决你的问题,请参考以下文章