最近遇到一个诡异的CUDA程序bug,我的Kernel里面有一个循环,遍历整个数据集。当数据量小的时候,程序没有问题,但当数据量增大的时候,整个屏幕会突然卡住,动不了,然后windows显示我的显卡驱动崩溃并恢复了,当然程序也挂了。
仔细检查程序的逻辑,怎么也找不到问题,在同桌小小哥的提示下,本想查看了CUDA的Sample程序deviceQuery看看内存到底用了多少,无意间发现一个配置项“Run time limit on kernels”,即deviceProp.kernelExecTimeoutEnabled。原来Kernel函数还有时间限制,在网上搜索了了解到其实这是windows的一个机制(TimeoutDetection and Recovery mechanism,TDR),即当Kernel函数运行的时候,由于这时候GPU在进行大量的运算,屏幕不能刷新,导致用户体验变差,为了防止这种情况,当Kernel函数运行时间超过一定限制时,windows会中断该程序,并恢复显卡驱动,保证用户体验的流畅,特别是大型游戏,GPU的运算量会很大。当然这是默认选项,在注册表里面可以更改该配置。
如果需要更改该配置项,在注册表中修改HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\GraphicsDrivers 下面的TdrLevel项(没有就自己添加),改为0(disable)即可。
参考:
1, Stackoverflow问题GPU card resets after 2 seconds