【问题标题】:Copying boundary values between groups in glsl compute shaders在 glsl 计算着色器中的组之间复制边界值
【发布时间】:2020-02-13 10:41:10
【问题描述】:

已经提出了很多这样的问题,但在我的情况下,我实际上需要共享数据

这是我的情况。我有一个程序,旨在用从顶部开始向下的值填充 3D 纹理。该程序填充了一种瀑布模型。

一个函数,它获取与 3D 纹理中的单元格相关联的值,以及它相对于当前单元格的位置,即f(x, position),并生成一个添加到当前单元格的新值。你可以把它想象成某种洪水填充

现在,如果我只需要相邻的值,我可以只使用幽灵点,问题是单个值从其当前位置向外扩散,因此相邻值将在我正在操作的当前块之外更新.

现在我不需要从相邻块传输整个数据块,我只需要在每一步中,当前网格周围相邻块的值。我仍然会使用幽灵点,但我需要将“新”值转移进去才能使用它们。

我的问题是,似乎每个人都说“使用另一个计算着色器调用”来解决这个问题。这是不可接受的,没有足够的工作来证明内核启动成本是合理的。

我看到的唯一选项是:

  • 使用原子整数跨组进行通信,让组知道他们可以使用与这些边界数据项对应的某些全局内存中的值
  • 通过将相邻单元格的值复制到单独的缓冲区中来使运行时间增加六倍,然后再次运行整个过程以考虑每一侧的新相邻值(立方体中有 6 个)。
  • 只对整个事物使用一个组调用。 GPU 正在做的其他事情可能足以证明这一点
  • 为 3D 纹理的每个“层”使用多个计算着色器调用,这需要将值转储到全局内存,然后为每一层读回它们,有效地使全局内存读取的成本加倍,并调用内核开销每个内核都需要按顺序启动。如果我可以在内核调用之间的共享内存中保留相同的内存,而不必重新读回它,这将缓解双延迟问题。

真的没有其他方法可以在计算着色器中复制边界吗?

【问题讨论】:

    标签: glsl gpu gpgpu vulkan compute-shader


    【解决方案1】:

    真的没有其他方法可以在计算着色器中复制边界吗?

    一般情况下,不会。

    无法保证相邻的边界组什么时候会被执行,那么你如何复制可能还不存在的呢?

    您可能能够阻塞和等待,但这效率低下(GPU 只会忙于等待)并且实际上可能是活锁,因为所有正在运行的组都被阻塞等待而新的组无法启动(因为被阻塞的组正在使用着色器核心的所有线程容量)。

    如果我理解你的算法正确,更糟糕的是你有一个循环依赖(边界双向传播到相邻块和从相邻块传播),所以除非你可以同时产生整个问题空间,否则它可以保证存在 -锁。

    【讨论】:

    • 我可以同时生成整个问题空间...并且不会出现活锁。假设您使用原子通信方法,您只需确保线程 A 具有其当前步骤的输出,然后线程 B 可以继续下一步,但两者都可以在没有彼此输入的情况下继续其当前步骤。出于您的目的,只需将其视为洪水填充,但多个洪水点可能会混合在一起。如果您在每次迭代中将程序作为单独的内核启动,只要上一步存在内存依赖关系,该程序仍然可以工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 2014-08-12
    相关资源
    最近更新 更多