如何在OpenCL(散布/聚集)中优化对直方图的写入?

时间:2019-11-04 16:46:21

标签: performance memory opencl histogram

我正在写类似于OpenCL中的粒子系统的东西。所有粒子都有一个位置和一个颜色,该位置和颜色是即时计算的。在所有计算的最后,我想在屏幕上显示所有粒子。为此,我想将所有粒子值(许多粒子值)添加到2D直方图中,因此直方图很大(例如1920 * 1080)。

enter image description here 请注意,所有组件(包括alpha组件)都被简单地求和。

当前,我为此简单地使用由uint4(或float4)组成的缓冲区,这在我的应用程序中是一个(巨大的)瓶颈,因为它是对全局内存的分散/聚集操作:

//Obviously hugely simplified for your reading pleasure
for (int i = 0; i < 1000; i++) {
    float calculatedYPixel = random() * 1080;
    float calculatedXPixel = random() * 1920;
    uint4 calculatedColour = (uint4) (0, 27, 244, 55); //something random as well
    histogram[(int) calculatedYPixel * histogramSize.x + (int) calculatedXPixel] += calculatedColour;
}

有什么办法可以加快速度吗?我目前正在使用OpenCL 1.2,但我也想听听涉及OpenCL 2,CUDA或OpenGL的解决方案。

  • 所有粒子都可以最终覆盖直方图的整个区域,因此,不可能进行任何类型的平铺/有组织的访问。
  • 我不介意在直方图中丢失几个粒子(例如,更新相互覆盖),速度要重要得多。

我也很好奇ROP(渲染输出单元)在这里是否可以使用,因为它们的功能看起来与这种类型的计算非常相似。从某些来源看来,GPU上的渲染缓冲区似乎可以针对例如写访问进行优化。

1 个答案:

答案 0 :(得分:1)

  

有什么办法可以加快速度吗?

通常,“我们如何在GPU上实现此串行算法?”这里可能是错误的问题。您需要退后一步,想一想什么并行算法可能会产生与串行算法相同的结果

您发布的代码可能与您所想到的实际代码并非特别接近。但是,如果我尝试根据某种分布用随机粒子填充空间,而不是一个一个地创建粒子并分别随机生成它们的位置,我会查看每个位置并根据分布函数为其生成随机样本。

从本质上讲,将“推”算法转变为“拉”算法。

如果您确实有足够的理由跟踪单个粒子,则这将变得更加困难,但是实际上我们在此没有得到足够的信息。

  

我也很好奇ROP(渲染输出单位)是否可以在这里使用,因为它们的功能似乎与这种类型的计算非常相似。从某些来源看来,GPU上的渲染缓冲区似乎可以针对例如写访问进行优化。

是的,如果您必须坚持使用“推送”方法,那么这绝对值得探讨,因为这听起来像基本上是您想要的添加剂混合。除了混合操作之外,模板缓冲区也可能是您感兴趣的。您可能希望研究所有主要3D API支持的渲染“点精灵”-渲染单个像素并不是3D应用程序通常要做的事情,因此不一定要针对GPU及其驱动程序进行优化,而是指向精灵基本上是用于绘制粒子系统的。