【问题标题】:Uniform affecting shader flow and performances均匀影响着色器流程和性能
【发布时间】:2015-04-05 19:51:47
【问题描述】:

我正在尝试使用 OpenGL 片段着色器,通过两次通道(一次水平,一次垂直)完成巨大的模糊 (300*300)。

我注意到将方向作为统一 (vec2) 传递比直接在代码中编写它(140 到 12 fps)慢大约 10 倍。

即:

vec2 dir = vec2(0, 1) / textureSize(tex, 0);
int size = 150;
for(int i = -size; i != size; ++i) {
    float w = // compute weight here...
    acc += w * texture(tex, + coord + vec2(i) * dir);
}

似乎比:

uniform vec2 dir;
/*
  ...
*/
int size = 150;
for(int i = -size; i != size; ++i) {
    float w = // compute weight here...
    acc += w * texture(tex, + coord + vec2(i) * dir);
}

用不同制服创建两个程序不会改变任何事情。

有谁知道为什么会有如此大的差异,为什么驱动程序没有看到“内联”目录可能更快?

编辑:将尺寸作为制服也有影响,但不如 dir。

如果您有兴趣查看它的外观(FRAPS 提供 fps 计数器):

快速说明:我在使用 OpenGL 4.2 和 glsl 420 的 nVidia 760M GTX 上运行。另外,puush 的 jpeg 负责图像中的颜色。

【问题讨论】:

    标签: c++ c opengl


    【解决方案1】:

    一个很好的猜测是UBOs 存储在共享内存中,但可能需要偶尔往返全局内存 (vram),而非统一版本将那一小段数据存储在寄存器或常量中记忆。

    但是,由于 OpenGL standard 没有规定您的数据存储在哪里,您必须查看分析器,并尝试更好地了解 NVIDIA 的 GL 实施的工作原理。

    我建议您从分析开始,使用NVIDIA PerfKitNVIDIA NSIGHT for VS。就算你这么想,现在也太麻烦了。如果你想编写高性能代码,你应该开始习惯这个过程。你会看到它最终变得多么容易。

    编辑:

    那么为什么它这么慢呢?因为在这种情况下,一个失败的优化(数据不在寄存器中)可能导致其他(如果不是大多数其他)优化也失败。而且,巧合的是,优化对于 GPU 代码快速运行是绝对必要的。

    【讨论】:

    • 所以你建议试试uniform vec2 dirUni; vec2 dir = dirUni; ?
    • 你可以尝试很多东西(你应该)。然而,即使这在 760M GTX 上使用 OpenGL 4.2 “有效”,它也可能在不同的卡和/或不同的 OpenGL 版本上显示出非常不同的性能。更不用说,不同的驱动程序。
    • 统一 vec2 dirUni; vec2 dir = dirUni;不会改变任何东西,但将尺寸视为制服确实会产生影响,但只有 50% 左右。
    • 你试过让size const 吗?将其从 int 更改为 float 怎么样? Might be faster.
    • 我目前正在研究 PerfKit(因为我没有使用 VS 也没有 eclipse)。这么小的(8 个字节)的东西怎么会有这么大的影响呢?只有两个drawcall。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-04
    • 1970-01-01
    • 2022-06-30
    • 1970-01-01
    • 2017-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多