当使用至少 2 次以上时,中间变量是否可以系统地提高性能且没有任何缺点?
让我们举一个实用的例子:
vec4 right = doubleUV + vec4(size.x, 0.0, 2.0 * size.x, 0.0);
vec4 left = doubleUV - vec4(size.x, 0.0, 2.0 * size.x, 0.0);
vec4 up = doubleUV + vec4(0.0, size.y, 0.0, 2.0 * size.y);
vec4 down = doubleUV - vec4(0.0, size.y, 0.0, 2.0 * size.y);
我们可以看到 2.0 * size.x
和 2.0 * size.y
并使用了多次。使用中间变量让我直观地将这段代码重构为:
float sizex2 = 2.0 * size.x;
vec4 right = doubleUV + vec4(size.x, 0.0, sizex2, 0.0);
vec4 left = doubleUV - vec4(size.x, 0.0, sizex2, 0.0);
float sizey2 = 2.0 * size.y;
vec4 up = doubleUV + vec4(0.0, size.y, 0.0, sizey2);
vec4 down = doubleUV - vec4(0.0, size.y, 0.0, sizey2);
除了可读性之外,这是一个可以系统应用的良好的“无需思考”的性能实践吗?或者我应该考虑额外乘法与变量分配的性能成本?
作为一个附带问题:额外的临时变量可能会损害性能吗?这很难测试,因为 GLSL 代码是针对 WebGL 的,并且将由多种编译器编译。某些 GLSL 编译器是否足够智能,可以将冗余的小代码片段分组?
最佳答案
对于简单的重复乘法,临时变量不会提高性能。但是,当进行更复杂的运算(如倒数、平方、平方根、点积)时,引入额外的变量可能会产生明显的影响(对于不会优化它的编译器)。
我不会担心插入临时变量的性能,因为这些变量将存储到 GPU 矢量化寄存器中。
但是,如果您添加的变量多于寄存器,您将面临以下风险:
- 在某些 GPU 上编译着色器失败。
- 寄存器溢出,其中需要直接从 GPU 执行单元本地内存 ( ARM mobile GPU docs ) 存储和访问变量。
作为替代方法(至少对我来说更清楚):
vec4 v1 = vec4(size.x, 0.0, 2.0 * size.x, 0.0);
vec4 right = doubleUV + v1;
vec4 left = doubleUV - v1;
vec4 v2 = vec4(0.0, size.y, 0.0, 2.0 * size.y);
vec4 up = doubleUV + v2;
vec4 down = doubleUV - v2;
Here您可以看到 GGX 着色模型以及分组为变量的操作的复杂性。
关于glsl - WebGL/GLSL 中间变量是否可以提高性能且没有任何缺点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76412220/