OpenCL内核的大量执行时间会导致崩溃

时间:2014-08-20 01:03:53

标签: opencl watchdog raymarching

我正在建立一个射线游行者来查看像mandelbox等的东西。它很棒。然而,在我目前的程序中,它使用每个工作人员作为从眼睛投射的光线。这意味着每个工作人员执行大量执行。因此,当查看一个非常复杂的对象或尝试以足够大的精度进行渲染时,会导致我的显示驱动程序崩溃,因为内核在单个工作程序上执行时间太长。我试图避免更改我的注册表值以使超时更长,因为我希望此应用程序在多台计算机上工作。

有没有办法解决这个问题?目前,每个工作项的执行完全独立于附近的工作项。我已经考虑过为GPU订阅缓冲区,该缓冲区将存储该光线上的当前进度,并且只执行少量迭代。然后,我会反复调用该程序,结果有望进一步完善。这个问题是我不确定如何处理分支光线(例如反射和折射),除非我有预期的最大数量。

任何人都有任何指示我应该采取什么措施来解决这个问题?我是OpenCL的新手,并且已经有很长一段时间了。我觉得好像我做错了或主要滥用OpenCL,因为我的单个工作项背后有很多逻辑,但我不知道如何拆分任务,因为它只是一系列步骤和检查和调整。

1 个答案:

答案 0 :(得分:5)

您遇到的崩溃是由nVIDIA的HW看门狗定时器引起的。此外,操作系统也可能检测到GPU没有响应并重新启动它(至少Windows7会这样做)。

你可以通过多种方式避免它:

  • 改善/优化内核代码以缩短时间
  • 购买更快的硬件($$$$)
  • 禁用看门狗定时器(但这不是一项容易的任务,并非所有设备都具有该功能)
  • 每次通过启动多个小内核减少排队到设备的工作量注意:这样做的开销很小,每个启动引入小内核

最后一个解决方案更简单直接。但如果可以的话,也可以尝试第一个。


例如,这样的调用(1000x1000 = 1M工作项,全局大小):

clEnqueueNDRangeKernel(queue, kernel, 2, NDRange(0,0)/*Offset*/, NDRange(1000,1000)/*Global*/, ... );

可以分为((100x100)x(10x10)= 1M)的许多小调用。由于全球规模现在要小100倍,因此不应触发看门狗:

for(int i=0; i<10; i++)
    for(int j=0; j<10; j++)
        clEnqueueNDRangeKernel(queue, kernel, 2, NDRange(i*100,j*100)/*Offset*/, NDRange(100,100)/*Global*/, ... );