Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GLSL division vs multiplication

Tags:

glsl

webgl

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;
like image 912
pailhead Avatar asked Oct 28 '25 05:10

pailhead


1 Answers

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.

like image 90
Kirill Dmitrenko Avatar answered Oct 31 '25 06:10

Kirill Dmitrenko