Frage

Warum ist es obligatorisch zu verwenden? -ffast-math mit G ++, um die Vektorisierung von Schleifen mithilfe zu erreichen doubles? Ich mag es nicht -ffast-math Weil ich keine Präzision verlieren möchte.

War es hilfreich?

Lösung

Sie verlieren nicht unbedingt Präzision mit -ffast-math. Es beeinflusst nur den Umgang mit NaN, Inf usw. und die Reihenfolge, in der Operationen ausgeführt werden.

Wenn Sie ein bestimmtes Code haben, in dem GCC nicht die Berechnungen neu ordnet oder vereinfacht, können Sie Variablen als verwendet werden, die mit einem verwendet werden asm Aussage.

Zum Beispiel führt der folgende Code einen Rundungsvorgang durch f. Die beiden jedoch f += g und f -= g Operationen werden wahrscheinlich von GCC optimiert:

static double moo(double f, double g)                                      
{                                                                          
    g *= 4503599627370496.0; // 2 ** 52                                    
    f += g;                                                                
    f -= g;                                                                
    return f;                                                            
}                                                                     

Auf x86_64 können Sie dies verwenden asm Aussage an die Anweisung von GCC, diese Optimierung nicht durchzuführen:

static double moo(double f, double g)                                      
{                                                                          
    g *= 4503599627370496.0; // 2 ** 52                                    
    f += g;                                                                
    __asm__("" : "+x" (f));
    f -= g;
    return f;
}

Sie müssen dies leider für jede Architektur anpassen. Auf PowerPC verwenden Sie +f Anstatt von +x.

Andere Tipps

Sehr wahrscheinlich, weil Vektorisierung bedeutet, dass Sie unterschiedliche Ergebnisse haben oder dass Sie schwimmende Punktsignale/-ausnahmen verpassen.

Wenn Sie für 32-Bit x86 zusammenstellen, dann verwenden GCC und G ++ Standard für die Verwendung des X87 für die Mathematik für Gleitpunkte. Auf 64-Bit-Standard-SSE kann und erzeugt der X87 unterschiedliche Werte für dieselbe Berechnung, sodass es unwahrscheinlich ist, G ++ wird überlegen, vektorisierend zu sein, wenn es nicht garantieren kann, dass Sie die gleichen Ergebnisse erhalten -ffast-math oder einige der Flaggen, die es einschalten.

Grundsätzlich kommt es auf die schwimmende Punktumgebung für vektorisierten Code an

-fno-math-errno -fno-trapping-math -fno-signaling-nans -fno-rounding-math

Sehen Sie sich jedoch zunächst diese Optionen an und stellen Sie sicher, dass sie die Korrektheit Ihres Programms nicht beeinflussen. -ffinite-math-only kann auch helfen

Da -ffast-math ermöglicht Operanden neu ordnen Dadurch kann viele Code vektorisiert werden.

Zum Beispiel, um dies zu berechnen

sum = a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + … a[99]

Der Compiler ist erforderlich die Ergänzungen durchführen der Reihe nach ohne -ffast-math, weil Gleitkomma Math weder kommutativ noch assoziativ ist.

Das ist der gleiche Grund Warum Compiler können nicht optimieren a*a*a*a*a*a zu (a*a*a)*(a*a*a) ohne -ffast-math

Das bedeutet, dass keine Vektorisierung verfügbar ist, es sei denn, Sie haben über sehr effiziente horizontale Vektor.

Jedoch, wenn -ffast-math ist aktiviert, der Ausdruck kann berechnet werden so was (Ansehen A7. Auto-Vectorization)

sum0 = a[0] + a[4] + a[ 8] + … a[96]
sum1 = a[1] + a[5] + a[ 9] + … a[97]
sum2 = a[2] + a[6] + a[10] + … a[98]
sum3 = a[3] + a[7] + a[11] + … a[99]
sum’ = sum0 + sum1 + sum2 + sum3

Jetzt kann der Compiler es einfach vektorisieren, indem jede Spalte parallel hinzugefügt und dann am Ende ein horizontales Hinzufügen durchführen

Tut sum’ == sum? Nur wenn (a[0]+a[4]+…) + (a[1]+a[5]+…) + (a[2]+a[6]+…) + ([a[3]+a[7]+…) == a[0] + a[1] + a[2] + … Dies gilt unter der Assoziativität, die sich nicht die ganze Zeit ansiedelt. Angeben /fp:fast Lassen Sie den Compiler Ihren Code um schneller ausführen - bis zu 4 -mal schneller für diese einfache Berechnung.

Bevorzugen Sie schnell oder präzise? - A7. Autovektorisierung

Es kann von der aktiviert werden -fassociative-math Flagge in GCC

Weitere Lesungen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top