c++ - 递归函数上的 OpenMP 并行化

标签 c++ drawing openmp

我正在尝试使用并行化来提高绘制具有分层排序对象的 3D 场景的刷新率。场景绘制算法首先递归遍历对象树,然后构建绘制场景所需的基本数据的有序数组。然后它多次遍历该数组以绘制对象/叠加层等。因为从我读到的 OpenGL 不是线程安全的 API,我假设数组遍历/绘图代码必须在主线程上完成,但我我在想我也许可以并行化填充数组的递归函数。关键是数组必须按照对象在场景中出现的顺序填充,因此所有将给定对象与数组索引相关联的功能都必须以正确的顺序完成,但是一旦分配了数组索引,我可以使用工作线程填充该数组元素的数据(这不一定是微不足道的操作)。所以这是我试图得到的伪代码。我希望您了解 xml-ish 线程语法。

recursivepopulatearray(theobject)
{
  <main thread>
  for each child of theobject
  {
     assign array index
     <child thread(s)>
       populate array element for child object
     </child thread(s)>
     recursivepopulatearray(childobject)
  }
  </main thread>
}

那么,是否可以使用 OpenMP 来实现这一点?如果可以,如何实现?是否有其他并行化库可以更好地处理这个问题?

附录:回应Davide's request for more clarification ,让我更详细地解释一下。假设场景是这样排序的:

-Bicycle Frame
  - Handle Bars 
  - Front Wheel
  - Back Wheel
-Car Frame
  - Front Left Wheel
  - Front Right Wheel
  - Back Left Wheel
  - Back Right Wheel

现在,这些对象中的每一个都有大量与之关联的数据,即位置、旋转、大小、不同的绘图参数等。此外,我需要多次遍历此场景才能正确绘制它。一个 channel 绘制对象的形状,另一个 channel 绘制描述对象的文本,另一个 channel 绘制对象之间的连接/关联(如果有的话)。不管怎样,如果我必须多次访问它们,从这些不同的对象中获取所有的绘图数据是相当慢的,所以我决定使用一次传递将所有这些数据缓存到一个一维数组中,然后所有实际的绘图过程只看数组。要注意的是,因为我需要以正确的顺序执行 OpenGL 压入/弹出,所以数组必须采用代表树层次结构的正确深度优先搜索顺序。在上面的示例中,数组必须按如下方式排序:

index 0: Bicycle Frame
index 1: Handle Bars 
index 2: Front Wheel
index 3: Back Wheel
index 4: Car Frame
index 5: Front Left Wheel
index 6: Front Right Wheel
index 7: Back Left Wheel
index 8: Back Right Wheel

因此,数组的顺序必须正确序列化,但是一旦我正确分配了该顺序,我就可以并行填充数组。例如,一旦我将 Bicycle Frame 分配给索引 0 并将 Handle Bars 分配给索引 1,一个线程可以填充 Bicycle Frame 的数组元素,而另一个线程可以填充 Handle Bars 的数组元素。

好的,我想在澄清这一点时,我已经回答了我自己的问题,所以谢谢 Davide。所以我发布了自己的 answer .

最佳答案

我认为你应该更好地澄清你的问题(例如,究竟什么必须连续完成以及为什么)

OpenMP(与许多其他并行化库一样)不保证各个并行部分的执行顺序,并且由于它们是真正并行的(在多核机器上),因此可能存在竞争条件如果不同的部分写入相同的数据。如果这可以解决您的问题,那么您当然可以使用它。

关于c++ - 递归函数上的 OpenMP 并行化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/835893/

相关文章:

c++ - 您如何为变量分配另一个类的值?

c++ - 用于 openmp 4.5 卸载到 (gpu) 设备的 nvptx gcc (9.0.0/trunk) 找不到 libgomp.spec

c++ - OpenMP卸载说 'fatal error: could not find accel/nvptx-none/mkoffload'

c++ - (通常)最快的方法来删除设置的交叉点

c++ - qt4 : call of update() on a single QGraphicsItem causes paint() on ALL QGraphicsItem

c++ - Boost Log运行时优化

java - java中文本到图像的定位

.net - 在我执行完所有更新之前,我可以暂停重新绘制表单吗?

geometry - ImageMagick 和饼图

macos - 尝试在 Mac 上安装 openMP/Clang