说我有类似的东西:
float foo;
float bar = baz / foo;
float qux = quux / foo;
当我执行以下操作时会发生什么:
foo = 1./foo;
float bar = baz * foo; //can i expect roughly the same number as with division?
floar qux = quux * foo; //is it always going to be faster?
鉴于webgl可以运行的硬件范围很广,我是否可以预期在编译时会发生这样的事情,或者像这样写它会更安全吗?
也很好奇
uniform float invFoo;
...
bar = baz * invFoo;
//instead of:
uniform float foo;
...
bar = baz / foo;
我不太明白this:
// A stupid compiler might use these as written: a divide, then add.
vec4 result1 = (value / 2.0) + 1.0;
vec4 result2 = (value / 2.0) - 1.0;
vec4 result3 = (value / -2.0) + 1.0;
// There are most likely converted to a single MAD operation (per line).
vec4 result1 = (value * 0.5) + 1.0;
vec4 result2 = (value * 0.5) - 1.0;
vec4 result3 = (value * -0.5) + 1.0;
我不明白愚蠢的编译器在这种情况下做了什么。是否缺少这可以作为单个MAD指令完成,或者是否缺少该除法可以表示为乘法(同时缺少MAD)。
此外,如何对这样的事情进行分组,但要转移内容:
vec2 foo,bar;
float baz;
baz = 1./baz;
vec2 temp = vec2( foo.x , bar.x ) * baz; //move but do one mult?
foo.x = temp.x;
bar.x = temp.y;
答案 0 :(得分:3)
我可以期待与分部大致相同的数字吗?
严格来说,不是:
$ cat a.cc
#include <iostream>
int main() {
const float a = 1.40129846e-45f;
const float b = a;
std::cout << "b / a: " << (b / a) << std::endl;
std::cout << "b * (1 / a): " <<(b * (1.f / a)) << std::endl;
return 0;
}
$ clang++ a.cc && ./a.out
b / a: 1
b * (1 / a): inf
$
然而,在或多或少的现实生活中,乘法和除法可以给出接近的结果。任何其他依赖于你将使用结果的计算的稳定性。如果那些计算是不稳定的(即,如果其任何参数甚至稍微改变,这种计算的结果会显着改变),那么结果可能存在差异。因此,您需要了解您使用的值,尤其是您所获得的精度。 GLSL浮点数并不总是32位IEEE浮点数,它们可能不太精确。
是否缺少这可以作为单个MAD指令完成,或者是 它错过了除法可以表示为乘法(at 同时错过了MAD)。
取决于特定编译器的特定怪癖,但可能是第二件事。