Domanda

Perché è obbligatorio da usare -ffast-math con G ++ per ottenere la vettorializzazione dei loop usando doubleS? Non mi piace -ffast-math Perché non voglio perdere la precisione.

È stato utile?

Soluzione

Non perdi necessariamente la precisione con -ffast-math. Influisce solo sulla gestione di NaN, Inf ecc. e l'ordine in cui vengono eseguite le operazioni.

Se si dispone di un codice specifico in cui non si desidera che GCC riordini o semplifica i calcoli, è possibile contrassegnare le variabili come utilizzate utilizzando un asm dichiarazione.

Ad esempio, il seguente codice esegue un'operazione di arrotondamento su f. Tuttavia, i due f += g e f -= g È probabile che le operazioni vengano ottimizzate da GCC:

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

Su x86_64, puoi usarlo asm Dichiarazione per istruire GCC di non eseguire tale ottimizzazione:

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

Dovrai adattarlo per ogni architettura, sfortunatamente. Su powerPC, usa +f invece di +x.

Altri suggerimenti

Molto probabilmente perché la vettorializzazione significa che potresti avere risultati diversi o potrebbe significare che si perdono segnali/eccezioni di punti galleggianti.

Se stai compilando per X86 a 32 bit, allora GCC e G ++ default a utilizzare l'X87 per il punto matematico mobile, su 64 bit, sono impostati predefiniti su SSE, tuttavia X87 può e produce valori diversi per lo stesso calcolo prendere in considerazione la vettorializzazione se non può garantire che otterrai gli stessi risultati a meno che non si usa -ffast-math O alcune delle bandiere che si accendono.

Fondamentalmente si riduce all'ambiente a punta mobile per il codice vettoriale potrebbe non essere lo stesso di quello per il codice non vettoriale, a volte in modi importanti, se le differenze non contano, qualcosa come

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

Ma prima cerca quelle opzioni e assicurati che non influenzino la correttezza del programma. -ffinite-math-only può anche aiutare

Perché -ffast-math consente operandi riordinamento che consente a molti codice di essere vettoriali.

Ad esempio per calcolare questo

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

Il compilatore è necessario Per fare le aggiunte sequenzialmente senza -ffast-math, perché la matematica a punta mobile non è né commutativa né associativa.

Questo è lo stesso motivo Perché i compilatori non possono ottimizzare a*a*a*a*a*a a (a*a*a)*(a*a*a) senza -ffast-math

Ciò significa che non è disponibile alcuna vettorializzazione a meno che non si disponga di un vettore orizzontale molto efficiente.

Tuttavia se -ffast-math è abilitato, l'espressione può essere calcolata come questo (Guarda a 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

Ora il compilatore può vettoriale facilmente aggiungendo ogni colonna in parallelo e quindi fare un aggiunto orizzontale alla fine

Fa sum’ == sum? Solo se (a[0]+a[4]+…) + (a[1]+a[5]+…) + (a[2]+a[6]+…) + ([a[3]+a[7]+…) == a[0] + a[1] + a[2] + … Questo è sotto associazione, che galleggia non aderisce, tutto il tempo. Specifica /fp:fast Consentono al compilatore di trasformare il codice in modo più veloce - fino a 4 volte più veloce, per questo semplice calcolo.

Preferisci veloce o preciso? - A7. Auto-vettorializzazione

Può essere abilitato da -fassociative-math Flag in GCC

Ulteriori letture

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top