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

Jon*_*arl 1 watchdog opencl raymarching

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

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

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

Dar*_*ros 5

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

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

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

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


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

clEnqueueNDRangeKernel(queue, kernel, 2, NDRange(0,0)/*Offset*/, NDRange(1000,1000)/*Global*/, ... );
Run Code Online (Sandbox Code Playgroud)

可以分为((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*/, ... );
Run Code Online (Sandbox Code Playgroud)