【问题标题】:Long-running cuda kernel stops when TDR kicks in当 TDR 启动时,长时间运行的 cuda 内核停止
【发布时间】:2013-12-13 19:32:13
【问题描述】:

我是 CPGPU 的新手,我有一个小的。我的程序需要大量的计算,所以当达到超时时,Windows TDR 启动,它会停止执行。 遗憾的是,我在运行我的程序的计算机上没有管理员权限,因此无法修改注册表项。我设法通过正在处理的图像行将问题分解为较小的问题,并尝试调用内核在 for 循环中重复。为了确保卡确实有时间响应操作系统,我在调用之间设置了一些睡眠时间,如下所示:

for(int row = 0; row<image.y; row++){
    printf("%d/%d\n", row, image.y);
    cudaMemset(dev_matrixes, 0, image.x*image.y*sizeof(short));
    countEnergyOfRow<<<B,BLOCK_DIM>>>(...);
    Sleep(750);
}

起初它似乎工作得很好,但在第 21 次迭代中,驱动程序被压坏了,TDR 再次击中。恢复后,CPU 继续调用内核,接下来的 490 次运行正常。我已经多次运行它,每次第 21 次迭代都是致命的。我还尝试从不同的(第 18 个)索引开始它,但同样,问题发生在第 21 次迭代(第 39 个索引处)。 我做错了什么,有什么我想念的吗?我应该以某种方式让 GPU 停止手动计数,还是只是增加睡眠时间?

【问题讨论】:

    标签: c++ loops cuda sleep


    【解决方案1】:

    除了 Windows TDR 之外,Windows WDDM 系统还需要进行批处理操作。因此,一种可能性是,即使单个内核调用没有超过超时时间,操作的批处理方式也会超过超时时间。

    您可以尝试的一件事是进一步减少内核的执行时间。如果你的内核的执行时间减少到 1/10 秒,那么即使是批处理操作也不应该导致超时。

    您可以尝试的另一件事是尝试通过在每次内核调用后发出 cudaStreamQuery(0); 调用来解决批处理问题。

    您还可以检查第 21 次迭代是否由于某种原因需要更长的时间;您可以添加cudaEvent 计时来测量每个内核调用的时间;我相信这会很有启发性。

    最好的解决方案是在不受 WDDM/TDR 约束的系统/GPU 上工作。

    【讨论】:

    • 非常非常感谢!确实是批处理操作,使其运行时间过长。不幸的是,我无法缩小内核,但在调用之前添加 cudaStreamQuery(0) 确实解决了问题。更准确地说,我也在 cudaMemset 之前添加了它,因为它也很长,并且它仍然在某个时候停止。现在它可以完美运行了。
    猜你喜欢
    • 2018-10-26
    • 2019-05-26
    • 2015-04-06
    • 2022-01-04
    • 1970-01-01
    • 2012-08-25
    • 2016-03-04
    • 1970-01-01
    • 2012-03-15
    相关资源
    最近更新 更多