【问题标题】:Detecting and recovering from Windows TDR?检测 Windows TDR 并从中恢复?
【发布时间】:2014-04-07 16:29:05
【问题描述】:

我遇到了一个奇怪的问题,即我正在处理的一些 OpenCL 代码,每隔一段时间,Windows TDR 就会启动并重置 GPU。有问题的内核只运行了 150 毫秒,并且在 TDR 将其杀死之前将运行数千次(在几个小时内),所以我确信内核本身不是罪魁祸首。

我担心的是,一旦 TDR 启动,内核就会死掉,程序就会陷入永恒的边缘状态。据我所知,对clFinish 的调用永远不会返回。

有没有办法检测内核是否已经死掉,以便可以优雅地处理它?

【问题讨论】:

    标签: c++ windows opencl


    【解决方案1】:

    我设法想出了一个解决方案,尽管它远非最佳。

    我已经修改了程序,以便 OpenCL 处理在单独的线程中完成。我在父进程和子进程之间创建了一个全局共享看门狗变量。当父进程将处理函数作为线程生成时,它将变量设置为当前时间(以毫秒为单位)。当处理线程完成时,它将看门狗变量重置为零。

    当父线程等待处理线程完成时,它会密切关注看门狗计时器。如果计时器超过某个阈值,则程序会强制终止自身而不等待子进程返回。

    无论是否设置了 Windows TDR,此解决方案都适用。如果设置了 TDR 并且驱动程序重置,则对 clFinish() 的调用将永远不会返回,并且一旦看门狗定时器跳闸,父级将终止。如果没有设置 TDR,则失控进程将冻结显示,但一旦看门狗定时器跳闸,父进程将终止处理,结束冻结。

    现在我已经设置了一个看门狗,我只是将我的程序包装在一个脚本中:如果它以错误终止(正返回码),那么程序将重新运行。

    【讨论】:

      【解决方案2】:

      理想情况下,您应该从 clFinish 或 clWaitForEvents 获取错误代码,其中包含在内核排队时生成的 OpenCL 事件对象。由于 TDR 重置了图形驱动程序,我认为任何 OpenCL 实现都不会可靠地工作,这意味着没有恢复路线。

      宁可完全禁用 TDR。仅当您调试陷入无限循环并永久保持 GPU 忙碌的代码时才值得。

      如果您想保留 TDR 但可以更改代码,则使用某种线程休眠功能将您的代码延迟几毫秒也可以缓解此问题,但会牺牲处理速度。这让显卡有机会响应显示渲染命令,从而不会触发 TDR。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-08-08
        • 1970-01-01
        • 1970-01-01
        • 2018-05-23
        • 2023-04-04
        • 2015-10-20
        相关资源
        最近更新 更多