2013-08-12 8 views
6

Ist es möglich, während der Laufzeit selektiv -ffast-math ein-/auszuschalten? Zum Beispiel das Erstellen der Klassen FastMath und AccurateMath mit der gemeinsamen Basisklasse Math, so dass man beide Implementierungen zur Laufzeit verwenden könnte? Dito für blinkende Unternormale auf Null, usw.Dynamic -ffast-math

Insbesondere weiß ich nicht, ob das Kompilieren mit -ffast-math einen Befehl ausgeben würde, der, sobald er ausgeführt wird, alle numerischen Berechnungen im Thread (zum Beispiel Einstellung) betrifft ein Flag, um Unternormale auf Null zu setzen).

+13

Sie müssten zwei Versionen kompilieren, eine mit der Optimierung und eine ohne. Verknüpfen Sie sie dann und wählen Sie aus, was zur Laufzeit aufgerufen werden soll. – Mysticial

+2

Es ist bedauerlich, dass http://stackoverflow.com/questions/7420665/what-does-gccs-ffast-math-actually- nur ein Beispiel gibt, aber '-fast-math's Effekt sind meistens (ganz?) Kompilierungszeit-Auswahlmöglichkeiten, wie z. B. Kompilieren von '/ 10' als' * 0,1' oder "Vereinfachen" von "a + bab" in "0" (es ist nicht Null für IEEE 754-Berechnungen). Daher, wie Mysticial sagt, gibt es keine Möglichkeit, das Flag zur Laufzeit ein- und auszuschalten: Sie müssen zwei Versionen kompilieren, wenn Sie das wirklich wollen. –

+1

@Mysticial machen Sie Ihren Kommentar in eine Antwort - es ist das einzige waaay ... – ldrumm

Antwort

3

Try this:

gcc -ffast-math -c first.c 
gcc -c second.c 
gcc -o dyn_fast_math first.o second.o 

Putting eindeutiger Namen Funktionen in first.c und second.c. Dies sollte den Trick machen. Es gibt selten "globale" Auswirkungen einer Compiler-Optimierung. Wenn eine existiert, wird die Verknüpfung wahrscheinlich aufgrund des Konflikts fehlschlagen.

Ich probierte eine kleine Probe ohne Problem.

Hier ist ein Beispiel.

first.c

extern double second(); 

double first() 
{ 
    double dbl; 

    dbl = 1.0; 
    dbl /= 10.0; 

    return dbl; 
} 

int main() 
{ 
    printf("first = %f\n", first()); 
    printf("second = %f\n", second()); 

    return 0; 
} 

second.c

double second() 
{ 
    double ddbl; 

    ddbl = 1.0; 
    ddbl /= 10.0; 

    return ddbl; 
} 

Kompilation

gcc -S first.c 
gcc -c first.s 
gcc -ffast-math -S second.c 
gcc -ffast-math -c second.s 
gcc -o prog first.o second.o 

die differe prüfen nce zwischen first.s und second.s und Sie werden diese finden:

movapd %xmm1, %xmm2 
divsd %xmm0, %xmm2 
movapd %xmm2, %xmm0 

wechselt:

mulsd %xmm1, %xmm0 

Beide Funktionen werden aufgerufen, und beide Rück das erwartete Ergebnis.

+1

Danke. Ich frage mich allerdings, ob so etwas machbar ist, ohne das Build-System zu ändern, das in meinem Fall Dutzende von Makefile-Skripten für Tausende von Quelldateien enthält. Gibt es ein #pragma schnell-Mathe? Googeln führt zu einem Fehlerbericht, der behauptet, dass ein solches Pragma in GCC funktionieren sollte, tut dies aber nicht. – Michael

+0

Ah, ich weiß nichts über ein Pragma oder andere Mittel. Nehmen Sie Änderungen an Einstellungen für bestimmte Ziele vor, wenn das hilft. – ash

4

Wenn Sie nicht mit dem Build-System Dreck möchten, können Sie folgendes tun:

#pragma fast-math push 
#pragma fast-math on 
[..] 
#pragma fast-math pop 

GCC eine etwas andere Syntax haben, aber ich würde erwarten, es ist auch möglich.