Say i've got something like:
float foo;
float bar = baz / foo;
float qux = quux / foo;
What happens when i do the following:
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?
Given the wide gamut of hardware webgl can run on, can i expect that something like this would happen under the hood when compiled, or is it just always safer to write it like this?
Also curious about
uniform float invFoo;
...
bar = baz * invFoo;
//instead of:
uniform float foo;
...
bar = baz / foo;
I don't quite understand 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;
I don't understand what a stupid compiler does in this context. Is it missing that this can be done as a single MAD instruction, or is it missing that the division can be expressed as a multiplication (at the same time missing the MAD).
Also, what about grouping something like this but moving stuff around:
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;
can i expect roughly the same number as with division?
Strictly speaking, no:
$ 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
$
However, in more or less real life examples, multiplication and division can give close result. Anything else depends upon stability of computation you'll use the result with. If those computations are unstable (i.e., result of such a computation changes significantly if any of its parameters changes even slightly), then there may be a difference in results. So you need to be aware of what values you use and especially what precision you've got. GLSL float's aren't always 32-bit IEEE floats, they may be less precise.
Is it missing that this can be done as a single MAD instruction, or is it missing that the division can be expressed as a multiplication (at the same time missing the MAD).
Depends upon particular quirks of a particular compiler, but probably the second thing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With