代码之家  ›  专栏  ›  技术社区  ›  ivano

如何在OS X中绕过CUDA代码上的GPU看门狗定时器限制

  •  1
  • ivano  · 技术社区  · 11 年前

    我目前正在使用OS X 10.9开发rMBP,运行openCV GPU/CUDA代码。我更具体地使用BruteForceMatcher_GPU knnMatchSingle/knnMatch功能。经过5秒的GPU计算后,OSX会覆盖并终止程序,这是一个众所周知的恢复过程,可以避免OSX的launchd或NVIDIA GPU驱动程序冻结屏幕。Windows和Linux允许关闭GPU看门狗定时器,但OSX不允许,这可能有道理。无论如何,我的问题是,在openCV中,是否有可能保存GPU内存状态,并在一定延迟后恢复,从而克服看门狗定时器的限制?如果没有,关于如何使用OSX的GPU看门狗定时器,还有其他想法吗?非常感谢

    附言:我已经安装了gfxCardStatus 2.3,以便能够看到显卡之间的切换。

    1 回复  |  直到 11 年前
        1
  •  1
  •   Dyrborg    11 年前

    在使用OpenCV GPU模块和低级别CUDA编程后,我也遇到了这个问题。简短的回答是否定的——你不能像在Windows中通过注册表项那样绕过看门狗计时器——或者更确切地说——尽管我在各种CUDA开发者论坛上尝试了一些建议,但我从未找到过这样做的方法。

    由于NVidia GPU的GPU架构,因此不可能保存GPU状态。一般来说,要在GPU上计算任何东西,您可以在CPU上初始化数据并将其保存在RAM中,将数据复制到GPU全局内存中,GPU核心可以访问该内存,进行计算,将结果保存在全局内存中并将其复制回CPU/RAM,CPU可以在那里访问结果,内核终止释放所有数据。当看门狗计时器启动时,内核将终止,所有数据都将丢失。

    因此,从技术上讲,要解决这个问题,只有两种可能的解决方案: 一种解决方法是只进行耗时小于5秒定时器(或系统上的任何定时器)的GPU计算,将中间结果保存到CPU/RAM,然后启动一个新内核,下一个数据在队列中等待。你一直这样做,直到完成为止。然而,这会对您的性能产生很大影响,因为您首先必须拆分数据,正确排队,并多次将数据复制到GPU和从GPU复制数据,因此您可能会根据数据损失很多性能。

    另一个解决方案是安装两个专用GPU-一个用作系统GPU,另一个只是坐在那里处理数字。至少在Windows和Linux上,这可以完美工作,而无需禁用看门狗计时器。我不知道OSX是否也是如此,因为我没有在Mac上使用多个CUDA GPU的经验。CUDA公开了一个功能,您可以在其中手动设置要使用的设备:

    http://developer.download.nvidia.com/compute/cuda/4_1/rel/toolkit/docs/online/group__CUDART__DEVICE_g418c299b069c4803bfb7cab4943da383.html

    默认的GPU总是索引0,根据我的经验,它是由您的系统设置为当前显示设备的GPU。因此,将索引设置为1将使用系统当前未使用的GPU(注意,我不确定SLI设置中的行为是否相同)。例如,我用来测试的Windows机器有一个8800GT作为显示设备,侧面有一个TESLA C2075。两者都支持CUDA,因此手动将TESLA设置为CUDA设备(索引1)意味着显示设备从未冻结,因此看门狗也从未启动。在我的带有GTX680/TESLA k20C组合的linux机器上也发生了同样的情况。

    值得注意的是,cudaSetDevice只知道CUDA设备,所以如果你的Nvidia卡上有集成GPU或AMD GPU,那么你就不能用cudaSetDevices在它们之间切换。它将始终使用启用CUDA的设备,或者完全失败。据我所知,没有cv::gpu:cudaSetDevice,所以我不知道您是否可以将此函数与OpenCV代码一起调用。如果您使用的是C而不是C++,那么您可能可以使用NVCC编译器,并在OpenCV函数之前实际调用一些本机CUDA(如cudaSetDevice)函数。

    然而,使用OpenCV,你对CUDA代码中发生的事情的控制要少得多(与编写自己的内核相比),而且可能不可能真正拆分数据并获得令人满意的结果。在那种情况下,我认为你的问题没有解决办法。除此之外,OSX喜欢根据MacBook Pro上当前的工作负载在多个GPU之间切换。

    当我在MacBook pro上遇到这个问题时,我在训练营中安装了Windows 7以及VS2010和CUDA工具包,禁用了看门狗计时器,并完美地运行了它。这不是一个完美的解决方案,但至少它允许我在将CUDA代码部署到测试服务器之前在本地开发CUDA代码。