2013-08-12 12 views
6

È possibile attivare selettivamente -ffast-math on/off durante il runtime? Ad esempio, creando classi FastMath e AccurateMath con la classe base comune Math, in modo che uno possa utilizzare entrambe le implementazioni durante il runtime? Idem per i subnormali lampeggianti a zero, ecc.Dinamica -ffast-math

In particolare, non so se la compilazione con -ffast-math emetterebbe un'istruzione che, una volta eseguita, influirà su tutti i calcoli numerici nel thread (ad esempio, impostazione un flag per svuotare i subnormali a zero).

+13

È necessario compilare due versioni, una con l'ottimizzazione e una senza. Quindi collegali e scegli quale invocare in fase di esecuzione. – Mysticial

+2

È un peccato che http://stackoverflow.com/questions/7420665/what-does-gccs-ffast-math-actually-do fornisca solo un esempio, ma gli effetti di '-ffast-math' sono per lo più (interamente?) scelte in fase di compilazione, come compilare '/ 10' come' * 0.1', o "semplificare" 'a + bab' in' 0' (non è zero per IEEE 754 calcoli). Pertanto, come dice Mysticial, non c'è modo di attivare e disattivare la bandiera in fase di esecuzione: è necessario compilare due versioni se è quello che si vuole veramente. –

+1

@Mysticial trasforma il tuo commento in una risposta - è l'unico waaay ... – ldrumm

risposta

3

Prova questo:

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

Mettere funzioni con nome univoco in first.c e secondario.e. Questo dovrebbe fare il trucco. Raramente c'è un impatto "globale" sull'ottimizzazione del compilatore. Se uno esiste, il collegamento probabilmente fallirà a causa del conflitto.

Ho provato un piccolo campione senza problemi.

Ecco un esempio.

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

secondario.e

double second() 
{ 
    double ddbl; 

    ddbl = 1.0; 
    ddbl /= 10.0; 

    return ddbl; 
} 

compilazione

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 

Controllare la differe nce tra first.s e second.s e troverete questo:

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

modifiche a questo:

mulsd %xmm1, %xmm0 

Entrambe le funzioni sono chiamati, ed entrambi restituire il risultato atteso.

+1

Grazie. Mi chiedo però se qualcosa del genere sia fattibile senza cambiare il sistema di build, che nel mio caso include dozzine di script in stile makefile per migliaia di file sorgente. Esiste un #pragma fast-math? Googling per questo porta a una segnalazione di bug che afferma che tale pragma dovrebbe funzionare in GCC, ma non lo fa. – Michael

+0

Ah, non conosco un pragma o altri mezzi. Apporta modifiche alle impostazioni per target specifici, se questo aiuta. – ash

4

Se non si vuole fare muck con il sistema di compilazione, è possibile effettuare le seguenti operazioni:

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

GCC può avere una sintassi leggermente diversa, ma mi si aspetterebbe che sia possibile anche.