【问题标题】:How much perf can I get using half_floats for vertex attribs?对顶点属性使用 half_floats 可以获得多少性能?
【发布时间】:2015-02-27 12:28:21
【问题描述】:

目前我有一个动态 VBO(每帧更新,粒子系统)。 我发送 4 个用于 pos 的浮点数和 4 个用于颜色的浮点数。

如果我改用 half_float 数据类型,我可以期待多少性能?是 5% 还是 30%?

假设我想以点精灵的形式发送 100k...500k 粒子。 所以我发送了大约 100k*8*4bytes = ~3MB

当然我知道各种 GPU 之间可能存在差异...

【问题讨论】:

  • 如果你有这么多的顶点,我要做的第一件事就是只使用三个浮点数来定位并省略齐次坐标(因为它通常是 1)。这将显着减小 VBO 的总大小。
  • 是的,这是另一个好主意:它将节省 1/8 的带宽。但是半浮动可以进一步减少这种情况
  • 以及如何有效地将数据从vec4数组复制到vec3数组中?只是一个简单的 for 循环?
  • 输入汇编器的性能通常与顶点结构本身的整体大小和对齐方式有关(32 或 64 字节往往是最有效的)。使用 float16s 可用于改进顶点大小/对齐。

标签: performance opengl directx gpu


【解决方案1】:

每次更改数据时,您为从全浮点数转换为半浮点数所支付的费用比为每半浮点数节省的 2 个字节所支付的费用要多。

因此,从长远来看,看看什么可以为您节省更多、更少的内存带宽或花费更多时间填充 VBO。如果 CPU 经常空闲(等待 vsync),那么以 CPU 时间为代价优化带宽将会胜出,但是如果大量时间花在 CPU 上进行物理处理,那么您将无法转换为半浮动。

除非你有一个通常不是内置类型的 very efficient conversion 函数,并且你可以承受我不会打扰的 CPU 命中率。

鉴于您正在寻找更紧凑的数据格式,那么我建议使用线性比例 (u)int16(将 uniform 设置为 true 以将 {-32768, 32767} 映射到 {-1, 1} 或 {0, 65565}改为 {0, 1}),如果您不需要接近 0 的精度,那么这将提供更好的精度。

【讨论】:

    【解决方案2】:

    开始时很可能不需要 4 个颜色的浮点数。

    您可能可以摆脱 4 个无符号字节。从 8 位定点数到浮点数的转换在 GPU 上非常便宜(这是它们最初的设计目的),因此您可以将颜色的内存需求降低 75%,而不会影响固有的性能。当然,正如其他人所提到的,对齐成为一个问题。从 16 字节更改为 4 字节颜色很容易弄乱 vec4 对齐的顶点数据结构,除非您填充它、添加一些额外的属性(例如 3D 顶点法线)或更改数据结构的另一个成员。

    vec3 位置加上 4 字节颜色非常适合缓存边界,除非您实际使用非1.0 同类协调(认真地)?这将为您提供与将所有内容切换为半浮点数相同的内存要求,但您仍然可以获得全精度位置。

    【讨论】:

    • 如何高效地从vec4转换为rgba8?还是直接在 rgba8 上执行计算会更好?我的初始测试显示性能提升不大......也许我在低效转换(vec4 数组到 vec3,然后 vec4 到 rgba8)上浪费时间
    • 老实说,我真的不希望在性能改进方面有太多期望。您在 CPU 上进行转换,然后每帧将其传输到 GPU,这将成为比内存带宽更多的性能瓶颈。最终将粒子模拟转移到 GPU 本身是理想的 - 由于变换反馈/计算着色器,如今这更容易实现。
    • 是的,这是一个不错的选择,但我只是想探索一下 CPU 粒子系统。在下一个“版本”中,我可能会坚持使用 GPU 方面。
    猜你喜欢
    • 1970-01-01
    • 2015-03-17
    • 2015-05-17
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-28
    相关资源
    最近更新 更多