2013-10-23 10 views
19

Wenn Sie diese sehr schöne Seite überprüfen:schnelle Quadratwurzeloptimierung?

http://www.codeproject.com/Articles/69941/Best-Square-Root-Method-Algorithm-Function-Precisi

Dieses Programm sehen werden:

#define SQRT_MAGIC_F 0x5f3759df 
float sqrt2(const float x) 
{ 
    const float xhalf = 0.5f*x; 

    union // get bits for floating value 
    { 
    float x; 
    int i; 
    } u; 
    u.x = x; 
    u.i = SQRT_MAGIC_F - (u.i >> 1); // gives initial guess y0 
    return x*u.x*(1.5f - xhalf*u.x*u.x);// Newton step, repeating increases accuracy 
} 

Meine Frage ist: Gibt es einen besonderen Grund, warum dies nicht so umgesetzt wird:

#define SQRT_MAGIC_F 0x5f3759df 
float sqrt2(const float x) 
{ 

    union // get bits for floating value 
    { 
    float x; 
    int i; 
    } u; 
    u.x = x; 
    u.i = SQRT_MAGIC_F - (u.i >> 1); // gives initial guess y0 

    const float xux = x*u.x; 

    return xux*(1.5f - .5f*xux*u.x);// Newton step, repeating increases accuracy 
} 

Wie aus Demontage, ich sehe ein MUL weniger. Gibt es einen Zweck, xhalf überhaupt erscheinen zu lassen?

+0

Wenn Ihr Compiler eine weniger mehrfach im zweiten Fall erzeugt dann vermute ich, dass entweder (a) Sie haben nicht aktiviert Optimierungen oder (b) Compiler saugt. ;-) –

+0

Vielleicht ist der Autor auf seinen bestes nicht, einige Bank laufen, wenn der einzige Unterschied eine 'MUL' die Zeit ist, sollten Sie mit Ihrem Code ein bisschen weniger hoch sein als mit seinem. –

+1

@PaulR Warum 'xhalf' überhaupt? Es erscheint nur einmal, warum sollte 'xhalf' eine Rolle spielen? – user1095108

Antwort

4

Es dass Vermächtnis Gleitkommamathematik sein könnte, die 80-Bit-Register verwendet, genauer war, als die Multiplikatoren, wo zusammen als Zwischenergebnisse in der letzten Zeile verknüpft, wo in 80-Bit-Registern gehalten.

Die erste Multiplikation in der oberen Implementierung nimmt die ganzzahligen Mathematik parallel statt, die sie Ressourcen verwenden unterschiedliche Ausführung folgt. Die zweite Funktion auf der anderen Seite sieht schneller aus, aber es ist schwer zu sagen, ob es wirklich wegen der oben genannten ist. Auch die const float xux = x * u.x; Die-Anweisung reduziert das Ergebnis auf 32-Bit-Float, was die Gesamtgenauigkeit verringern kann.

Sie könnten diese Funktionen Kopf an Kopf testen und sie mit der Funktion sqrt in math.h vergleichen (verwenden Sie double nicht float). Auf diese Weise können Sie sehen, welche schneller und welche genauer ist.