均匀影响着色器流程和性能

Posted

技术标签:

【中文标题】均匀影响着色器流程和性能【英文标题】: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 计数器):

uniform blur.

"inline" blur.

no blur.

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

【问题讨论】:

【参考方案1】:

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

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

我建议您从分析开始,使用NVIDIA PerfKit 或NVIDIA 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。

以上是关于均匀影响着色器流程和性能的主要内容,如果未能解决你的问题,请参考以下文章

带有着色器的 2D 照明 - 受窗口大小影响的光半径

opengl ---几何着色器

现代硬件上的 OpenGL 可分离着色器程序和管道性能

影响整个屏幕的Libgdx着色器

帧缓冲纹理出现白色(片段着色器不影响它)

GLSL 几何着色器的性能出乎意料地变慢