【问题标题】:OpenGL atomic counters buffer aliasing performanceOpenGL 原子计数器缓冲混叠性能
【发布时间】:2016-11-05 10:30:02
【问题描述】:

如果我在着色器“A”中使用原子计数器进行渲染/计算调度,然后将该计数器别名为着色器“B”中的缓冲区以进行后续渲染/计算调度,但在第二次调度中声明它作为制服或 SSBO 而不是实际的原子计数器,我应该注意什么性能影响? (假设采取了适当的 glMemoryBarriers() 等)

我知道一些 AMD 硬件至少有有限的专用原子硬件单元。我猜在这种情况下,如果别名为 SSBO,计数器结果稍后会写入缓冲区?所以可能在这种情况下,最好让原子计数器永远不会别名为任何未明确声明为原子计数器的东西?

在有人问起之前,我无法使用大量相关硬件来测试自己什么是最好的,所以我想知道这方面是否有一般的经验法则?

【问题讨论】:

  • "假设采取了适当的 glMemoryBarriers()" 没有。标准不认为原子计数器是incoherent memory accesses。因此,它们不需要在渲染调用之间进行任何显式同步工作。内部屏障可用于对原子操作进行排序,但除此之外,不能。
  • 另外,如果原子计数器不打算存储在缓冲区中(因此可以被任何读取缓冲区的操作读取),那么它们的存储将不会由缓冲区对象支持。它们只是上下文状态或您可以在发出渲染调用之前设置为值的东西。请注意,这是提案早期迭代的一部分,但已被放弃。
  • 啊,感谢您澄清,在使用原子计数器的调度/绘制之间的渲染传递之间不需要障碍 - 很高兴知道,感谢进一步的信息。但这仍然让我思考一个实际问题,例如在第二次抽奖中,将原子计数器声明为原子计数器还是仅仅作为 SSBO 中的另一个变量更好?

标签: opengl counter atomic


【解决方案1】:

性能不是您的问题。你的问题是它是否会起作用。

根据 OpenGL 内存模型的规则,如果您执行一些操作原子计数器的操作,并且在该渲染操作之后从该缓冲区读取,那么您需要能够获得所有原子计数器的结果操纵。那代表同步执行。

这都是真的...除非您尝试从中读取它作为原子计数器。因为那样的话,执行模型变得...不太明确。 rendering calls 同步原子计数器访问不需要实现。

现在,原子计数器操作的性质并没有因此而改变。例如,如果您只增加或减少一个计数器,您仍然可以保证在渲染调用中获得唯一值。而如果你修改了计数器的缓冲存储,然后执行一个计数器操作,下一个操作会看到修改(由于同步操作)。

但如果修改此内存的唯一操作是原子计数器,那么使用读取原子计数器并不能保证从之前的渲染命令中看到原子计数器操作。

所以是的,访问原子计数器的变量将比使用 SSBO 或 UBO 或其他任何方式更快。但是你不会得到正确的答案。所以这不是一个好的权衡;)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-03
    • 1970-01-01
    • 2014-02-11
    • 2015-11-04
    相关资源
    最近更新 更多