OpenCL计算导致屏幕冻结

6
正如标题所述,当我运行我的OpenCL内核时,整个屏幕停止重绘(显示器上的图像保持不变,直到我的程序完成计算。即使我将其从笔记本电脑上拔下并重新插入 - 始终显示相同的图像),计算机似乎也不会对鼠标移动做出反应 - 光标保持在同一位置。
我不确定为什么会发生这种情况。这可能是我的程序中的错误吗,还是这是标准行为?
在谷歌上搜索时,我发现了AMD论坛上的this线程,有些人认为这是正常现象,因为GPU在进行计算时无法刷新屏幕。
如果这是真的,是否仍然有任何方法可以解决这个问题?
我的内核计算可能需要几分钟时间,并且在整个时间内让我的计算机几乎无法使用真的很痛苦。
编辑1:这是我的当前设置:
  • 显卡是 ATI Mobility Radeon HD 5650,拥有512 MB的内存,并使用来自AMD官网的最新Catalyst beta驱动程序
  • 显卡是可切换的 - Intel集成/ATI专用卡,但我在BIOS中禁用了切换,否则无法在Ubuntu上安装驱动程序。
  • 操作系统是Ubuntu 12.10(64位),但在Windows 7(64位)上也会出现此问题。
  • 我通过HDMI连接了我的显示器(但笔记本屏幕也会冻结,所以这不应该是问题)

编辑2:经过一天的代码调试,我采纳了你们的建议并将算法更改为以下伪代码:

for (cl_ulong chunk = 0; chunk < num_chunks; chunk += chunk_size)
{
  /* set kernel arguments that are different for each chunk */
  clSetKernelArg(/* ... */);

  /* schedule kernel for next execution */
  clEnqueueNDRangeKernel(cmd_queue, kernel, 1, NULL, &global_work_size, NULL, 0, NULL, NULL);

  /* read out the results from kernel and append them to output array on host */
  clEnqueueReadBuffer(cmd_queue, of_buf, CL_TRUE, 0, chunk_size, output + chunk, 0, NULL, NULL);
}

现在我将整个工作负载分成块,一部分在主机上处理,一部分发送到GPU。对于每个数据块,我都会排队一个新的内核,并将其结果附加到正确的偏移量处的输出数组中。
这是您所说的计算应该如何分割吗?
这似乎是解决冻结问题的方法,而且现在我能够处理比可用GPU内存更大的数据,但我还需要进行一些良好的性能测量,以确定适当的块大小...

不确定您指的是哪个配置,但我已经更新了我的问题,并提供了有关我的当前硬件设置的信息。 - jcxz
是的,你对分配工作量的想法是正确的。 - chippies
好的,感谢确认。我想我会接受你的答案并关闭这个话题,因为这基本上解决了我目前的问题。我可能会进行额外的调试,并尝试找出是否有其他原因导致停顿,但我不认为我会很快得到任何结果... - jcxz
3个回答

7
每当GPU运行OpenCL内核时,它完全专注于OpenCL。一些现代的Nvidia GPU是例外,我认为从GeForce GTX 500系列开始,如果这些内核没有使用所有可用的计算单元,它们可以运行多个内核。
您的解决方案是将计算分成多个短内核调用,这是最好的全面解决方案,因为即使在单个GPU机器上也可以工作,或者投资于一个廉价的GPU来驱动您的显示器。
如果您要在GPU上运行长时间内核,则必须禁用GPU的超时检测和恢复,或将超时延迟设置为大于最大内核运行时间(更好,因为仍然可以捕获错误),请参见此处以了解如何执行此操作。

谢谢你的回答和提供的链接。我看了一下我的寄存器,但是唯一的条目是TdrDelay,它被设置为60,这很有趣,因为MSDN链接中指定默认值为2秒,而我不记得修改任何这些内容。此外,尽管我的内核可以运行2-4分钟(取决于输入),但我从未遇到过应用程序的过早结束(如果系统在GPU上杀死我的内核,那就是我认为的结果)。即使运行时间很长,结果仍然是正确的... - jcxz

2
每次我遇到显示器冻结或“显示驱动程序停止响应并已恢复”时,都是由于一个错误引起的。这可能会冻结整个系统,我唯一能做的就是重置。相反,现在我首先在CPU上进行开发。这从未导致过整个系统崩溃。这种方式也更容易调试,因为我可以使用printf。一旦我在CPU上成功地消除了代码中的bug,我就会尝试在GPU上运行它。

谢谢你的回答。实际上,内核应该是没问题的,我在 CPU 上开发了它,现在正在尝试在 GPU 上运行它。而且我的电脑并没有像崩溃一样无法恢复,只是视频输出会冻结,只要我的内核处于活动状态,整个时间都是如此。但是,一旦它完成了,我的电脑就会正常运行,甚至没有报告任何错误... - jcxz

1
我是opencl的新手,遇到了类似的问题。我发现短时计算可以正常工作,但长时间的计算会导致鼠标光标冻结。对于我的问题,Windows在托盘区域留下一个黄色三角形,并在事件日志中放置一条消息,指出“显示驱动程序已停止响应并已恢复”。我找到的解决方法是将计算分成小部分,每个部分不超过几秒钟。这些部分依次运行,但显卡驱动程序似乎能够保持足够的状态以保持其正常工作。如果我将global_work_size设置为足以最大化吞吐量的值,则视频响应速度非常慢,但驱动程序重新启动/鼠标冻结问题永远不会发生。

谢谢你的回答,我查看了事件查看器,但没有发现任何警告或类似的迹象。我用伪代码编辑了我的新算法的问题。这是你想要如何分解计算的方式吗? - jcxz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接