加法赋值会导致GLSL中的依赖链吗?

问题描述 投票:0回答:1

我经常看到这样的示例 GLSL 代码:

    vec4 sum = texture2D(texture, uv) * 4.0;
    sum += texture2D(texture, uv - halfpixel.xy * offset);
    sum += texture2D(texture, uv + halfpixel.xy * offset);
    sum += texture2D(texture, uv + vec2(halfpixel.x, -halfpixel.y) * offset);
    sum += texture2D(texture, uv - vec2(halfpixel.x, -halfpixel.y) * offset);

这不会在编译后的代码中引入依赖链吗?即使有也没关系吗?

编辑:

我希望我正确地总结了这一点。现代 CPU 和 GPU 具有调度程序,可以在同一时钟周期内同时运行某些指令(例如 Intel 上的

ADD
FADD
)。仅当操作不是要求它们分开的依赖链的一部分时,这才有可能。

这是一个依赖链的示例,在调度程序可以继续执行下一个语句之前,需要计算每个加法:

sum2 = a + b;
sum2 += c;     // needs to know a+b
sum2 += d;     // needs to know sum2+c
sum2 += e;     // needs to know sum2+d
sum2 += f;     // needs to know sum2+e

此代码是等效的(尽管它至少需要两个额外的累加器,并且使用浮点数可能会给出与上面代码不同的答案),但在我们到达最后一行之前不存在依赖链(有两个)。因此,在允许的 CPU/GPU 上,可以安排前三行同时执行:

a1 = a + b;
a2 = c + d;
a3 = e + f;

sum1 = a1 + a2 + a3;

就我问题顶部的代码而言,我不知道它是否重要。如果纹理查找不能并行完成,那么可能就不能。如果可以的话,那么也许?这就是我问的原因。

opengl glsl
1个回答
0
投票

让我们考虑一下您的添加示例:

sum2 = a + b;
sum2 += c;     // needs to know a+b

现在,应该问一个问题:什么“需要知道a+b”?因为这个表达式包含了几个步骤。是的,它与

+=
进行
sum2
运算,但在此之前,它必须首先计算表达式
c
sum2

从硬件的角度来看,评估

c

 基本上是无操作的,但这并不重要。毕竟,语句 
c += sum2;
 同样依赖于 
a+b
。这是因为计算 
sum2
 需要首先计算程序中该点用于生成 
sum2
 的所有表达式。

正是对

sum2

 的评估使得语句具有依赖性,
而不是c
 的评估。从技术上讲,如果您使用 
sum2
 而不是 
+=
 进行纯赋值操作,它就不会具有依赖性(因为它会覆盖以前的值),因此单独求值不会产生依赖性,但现在不用介意。 

重点是,当我们查看所有这些纹理表达式时,我们可以看到

texture2d

 调用独立于求和操作且彼此独立。因此,实现可以按照自己想要的任何顺序自由地评估它们。

这有关系吗?不;纹理获取并不便宜,并且重新排序这些东西并不会让它们变得更便宜。四个连续向量相加的成本是您最不需要担心的。

© www.soinside.com 2019 - 2024. All rights reserved.