2

我目前正在构建一个光线行军来查看诸如曼德尔盒之类的东西。它工作得很好。但是,在我当前的程序中,它使用每个工人作为从眼睛投射的光线。这意味着每个工作人员都有大量的执行。因此,当查看一个非常复杂的对象或尝试以足够大的精度进行渲染时,它会导致我的显示驱动程序崩溃,因为内核在单个工作人员上执行的时间太长。我试图避免更改我的注册表值以延长超时时间,因为我希望此应用程序可以在多台计算机上运行。

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

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

4

1 回答 1

6

您遇到的崩溃是由 nVIDIA 的硬件看门狗定时器引起的。此外,操作系统也可能会检测到 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*/, ... );
于 2014-08-22T09:16:51.357 回答