Ser*_*gey 8 opengl performance glsl vectorization
所有现代GPU都具有标量架构,但着色语言提供了各种矢量和矩阵类型.我想知道,GLSL源代码的标量化或矢量化如何影响性能.例如,让我们定义一些"标量"点:
float p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y;
p0x = 0.0f; p0y = 0.0f;
p1x = 0.0f; p1y = 0.61f;
p2x = 0.9f; p2y = 0.4f;
p3x = 1.0f; p3y = 1.0f;
Run Code Online (Sandbox Code Playgroud)
和它们的向量等价物:
vec2 p0 = vec2(p0x, p0y);
vec2 p1 = vec2(p1x, p1y);
vec2 p2 = vec2(p2x, p2y);
vec2 p3 = vec2(p3x, p3y);
Run Code Online (Sandbox Code Playgroud)
有了这些要点,以下哪些数学上等效的代码将运行得更快?
标量代码:
position.x = -p0x*pow(t-1.0,3.0)+p3x*(t*t*t)+p1x*t*pow(t-1.0,2.0)*3.0-p2x*(t*t)*(t-1.0)*3.0;
position.y = -p0y*pow(t-1.0,3.0)+p3y*(t*t*t)+p1y*t*pow(t-1.0,2.0)*3.0-p2y*(t*t)*(t-1.0)*3.0;
Run Code Online (Sandbox Code Playgroud)
或它的等价矢量:
position.xy = -p0*pow(t-1.0,3.0)+p3*(t*t*t)+p1*t*pow(t-1.0,2.0)*3.0-p2*(t*t)*(t-1.0)*3.0;
Run Code Online (Sandbox Code Playgroud)
?
或者它们在现代GPU上运行速度是否相等?
上面的代码只是一个例子.这种"可矢量化"代码的现实例子可以执行更重的计算,其中更多的输入变量来自全局ins,制服和顶点属性.
最好的选择是对您认为可以与此代码一起使用的所有系统(即 GPU)进行基准测试,并找出哪些系统使用矢量化代码更快,哪些系统使用标量化代码更快。然后,您将编写两个版本的代码(或者更有可能的是多个版本),并编写运行时逻辑以根据正在使用的 GPU/驱动程序切换正在使用的版本。
这当然是一个巨大的麻烦。大多数程序员不会这样做;GPGPU 程序员通常只使用一种服务器/GPU 节点类型,因此他们的代码将专门针对单一架构进行定制。与此同时,在 AAA 游戏工作室(这是唯一有预算和人力来处理此类任务的地方),他们通常只是让 NVidia 和 AMD 自己解决这个问题,NVidia/AMD 会写得更好,这些游戏使用的着色器的更优化版本,将它们添加到驱动程序中,并告诉驱动程序替换为更好的着色器,而不是任何 Gearbox/Bethesda/任何试图加载的着色器。
重要的是,对于您的用例,最好的选择是专注于使代码更易于维护;与任何“过早的优化”相比,这将为您节省更多的时间,并使您的程序运行得更好(我们要明确的是,这基本上就是您正在做的事情)。
| 归档时间: |
|
| 查看次数: |
674 次 |
| 最近记录: |