2017-05-18 8 views
3

Say habe ich habe so etwas wie:GLSL Division vs Multiplikation

float foo; 

float bar = baz/foo; 
float qux = quux/foo; 

Was passiert, wenn ich wie folgt vorgehen:

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? 

das breite Spektrum von Hardware webgl Da kann auf laufen, ich kann erwartet, dass so etwas unter der Haube passiert, wenn es kompiliert wird, oder ist es einfach immer sicherer, es so zu schreiben?

auch neugierig

uniform float invFoo; 
... 
bar = baz * invFoo; 
//instead of: 
uniform float foo; 
... 
bar = baz/foo; 

ich nicht ganz this verstehen:

// 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; 

Ich verstehe nicht, was für eine dumme Compiler in diesem Zusammenhang der Fall ist. Fehlt es, dass dies als einzelne MAD-Anweisung gemacht werden kann, oder fehlt, dass die Division als Multiplikation ausgedrückt werden kann (gleichzeitig fehlt die MAD).

Und was ist so etwas wie diese Gruppierung aber bewegten Material um:

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; 

Antwort

3

kann ich erwarten, dass etwa die gleiche Zahl wie bei Teilung?

streng genommen nicht:

$ 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 
$ 

jedoch in mehr oder weniger realen Beispielen, Multiplikation und Division knappes Ergebnis geben kann. Alles andere hängt von der Stabilität der Berechnung ab, mit der Sie das Ergebnis verwenden werden. Wenn diese Berechnungen instabil sind (d. H. Das Ergebnis einer solchen Berechnung ändert sich signifikant, wenn sich irgendeiner ihrer Parameter nur geringfügig ändert), dann kann es einen Unterschied in den Ergebnissen geben. Sie müssen also wissen, welche Werte Sie verwenden und vor allem welche Präzision Sie haben. GLSL-Floats sind nicht immer 32-Bit-IEEE-Floats, sie können weniger präzise sein.

Ist es fehlt, dass dies als eine einzige MAD Anweisung durchgeführt werden kann, oder ist es fehlt, dass die Teilung als Multiplikation ausgedrückt werden kann (bei gleichzeitig die MAD fehlt).

Hängt von bestimmten Macken eines bestimmten Compilers ab, aber wahrscheinlich die zweite Sache.

+0

Danke für die Antwort. Um in dem MAD-Beispiel sicher zu sein, in den meisten Fällen, in denen Berechnungen nicht instabil sind, wenn ich eine Division gefolgt von einer Addition habe, sollte ich das Inverse berechnen und eine Multiplikation durchführen, die zu einem einzigen MAD führt, oder sicher? – pailhead

+0

Könnten Sie auch das letzte Code-Snippet sehen, ich habe es gerade aktualisiert. – pailhead

+0

@pailhead yep, die wahrscheinlich Code erzeugen, der zumindest nicht langsamer ist. Sie müssen nur sicher sein, dass dies Ihren Ergebnissen nicht schadet, z. indem Sie es einfach ausprobieren und prüfen, ob sich die Qualität der gerenderten Bilder nicht geändert hat. –