2010-04-19 6 views
12

Sto lavorando a un solutore Navier-Stokes fluidodinamico che dovrebbe funzionare in tempo reale. Quindi, le prestazioni sono importanti.L'aritmetica del punto fisso valuterà il mio problema?

In questo momento, sto osservando un numero di loop stretti che rappresentano una frazione significativa del tempo di esecuzione: non c'è un singolo collo di bottiglia. La maggior parte di questi cicli esegue un calcolo aritmetico in virgola mobile, ma vi sono molte ramificazioni nel mezzo.

Le operazioni in virgola mobile sono principalmente limitate a aggiunte, sottrazioni, moltiplicazioni, divisioni e confronti. Tutto ciò viene fatto usando float a 32 bit. La mia piattaforma di destinazione è x86 con almeno le istruzioni SSE1. (Ho verificato nell'output dell'assemblatore che il compilatore genera effettivamente le istruzioni SSE.)

La maggior parte dei valori in virgola mobile con cui sto lavorando ha un limite superiore ragionevolmente piccolo e la precisione per valori vicini allo zero non è 'molto importante. Quindi il pensiero mi è venuto in mente: forse passare all'aritmetica a punto fisso potrebbe accelerare le cose? So che l'unico modo per essere veramente sicuri è misurarlo, potrebbero essere necessari giorni, quindi mi piacerebbe conoscere le probabilità di successo in anticipo.

Il punto fisso era di gran moda ai tempi di Doom, ma non sono sicuro di dove si trova anno 2010. Considerando quanto il silicio oggi è pompato in prestazioni in virgola mobile, c'è una possibilità che fissa- l'aritmetica dei punti mi darà ancora un significativo aumento di velocità? Qualcuno ha qualche esperienza del mondo reale che potrebbe applicarsi alla mia situazione?

+2

La ramificazione è probabilmente il più grande killer delle prestazioni. Cerca di ridurlo il più possibile. E no, non fare punto fisso. – phkahler

+1

Ho trovato il contrario. In alcuni casi, potevo sostituire la ramificazione con qualche altra aritmetica in virgola mobile, ma questo rallentava le cose. – Thomas

+1

indietro, in passato ho usato hardware SIMD a punto fisso specializzato ed è stato un enorme dolore al collo! Ci penserei due volte a riconsiderare l'aritmetica in virgola fissa. Vuoi passare la maggior parte del tempo a gestire le complessità dell'aritmetica in virgola fissa o risolvere il tuo problema più grande? Le CPU di oggi offrono più potenza e contengono FPU - io preferirei una soluzione in virgola mobile. Piuttosto, dedica del tempo a cercare di mantenere la pipeline piena, piuttosto che pensare all'aritmetica in virgola fissa. – Tilo

risposta

3

Come altri hanno già detto, se si sta già utilizzando la SIMD a virgola mobile, dubito che si otterranno molti miglioramenti con il punto fisso.

Hai detto che il compilatore sta emettendo le istruzioni SSE, ma non sembra che tu abbia provato a scrivere il tuo codice SSE vettoriale. Non so quanto siano bravi i compilatori di solito, ma è qualcosa su cui indagare.altri

Due aree da esaminare sono:

  1. di accesso alla memoria - se tutti i tuoi calcoli sono fatti in SSE, quindi cache miss potrebbero essere prendendo più tempo di quanto la matematica reale.

    1. È possibile eseguire il precaricamento dei dati con ad es. _mm_prefetch o __builtin_prefetch (a seconda del tuo compilatore/piattaforma).
    2. Controlla le tue costose funzioni per l'aliasing tra ingressi e uscite; questi possono portare a letture/scritture di memoria extra.
    3. Considerare la memorizzazione dei dati in modo diverso - se i risolutori di solutori di solidi per x coordinate indipendentemente da y, potrebbe essere più cache friendly per memorizzarli in array diversi. Se sono risolti per insieme, prendere in considerazione interleaving (ad esempio x y x y ...)
  2. apertolo - si dovrebbe essere in grado di ottenere un miglioramento delle prestazioni da srotolare i loop interni. L'obiettivo non è (come molti pensano) ridurre il numero di controlli di fine ciclo. Il vantaggio principale è quello di consentire l'interleaving delle istruzioni indipendenti, per nascondere la latenza delle istruzioni. Esiste una presentazione here dal titolo Ottimizzazione VMX: acquistando un livello che potrebbe aiutare un po '; è incentrato sulle istruzioni di Altivec su Xbox360, ma alcuni consigli di srotolamento potrebbero aiutare anche su SSE.

Come altre persone hanno menzionato, profilo, profilo, profilo. E poi facci sapere cosa è ancora lento :)

PS - in uno dei tuoi altri post here, ti ho convinto a utilizzare SOR anziché Gauss-Seidel nel tuo risolutore di matrice. Ora che ci penso, c'è una ragione per cui non stai usando un risolutore tridimensionale?

+0

Ho provato la mia mano a un po 'di assemblaggio SSE, ma il compilatore è più bravo di me.Ho dovuto fare troppo shuffling per ottenere i valori nei posti giusti prima di eseguire 4 moltiplicazioni simultanee. Tuttavia, questo è stato il mio primo codice assembly x86 in assoluto, quindi forse è possibile comprimere più prestazioni. – Thomas

+0

Il mio sistema è abbastanza piccolo da adattarsi completamente alla cache L2; meno di 400 kB, tutti insieme. Sarebbe comunque utile considerare la cache L1 oltre a quella? – Thomas

+0

Il compilatore non arrotolerà i loop su '-O3'? La previsione del ramo non lo farà comunque? Ho sempre pensato che lo srotolamento fosse una cosa del passato. Sono riuscito a rimuovere una dipendenza di scrittura/lettura nel solutore SOR, a proposito, utilizzando uno schema rosso/nero. Questo ha fatto un'enorme differenza. (Quando quella presentazione parlava della caratteristica della lingua che non si deve nominare, ho pensato: "A cosa serve goto' ?, userei un modello." Diapositiva successiva: Metaprogrammazione dei modelli.) Comunque, lo farò dare "manuale" (cioè modello) srotolare una prova. – Thomas

5

Stick con virgola mobile. Punto fisso è davvero utile solo se si può lavorare con 8 bit o 16 bit e utilizzare SIMD (l'elaborazione dell'immagine e l'audio sono tipici casi d'uso per questo).

Le moderne CPU hanno in genere 2 FPU ed è possibile emettere fino a 2 istruzioni FP per ciclo di clock. Hai anche la possibilità di ottimizzare utilizzando 4 vie FP SIMD (SSE).

Se si sta ancora lottando per ottenere buone prestazioni, provare a utilizzare un compilatore migliore, come ICC di Intel. Inoltre, gli eseguibili Intel a 64 bit tendono a essere un po 'più veloci rispetto ai loro equivalenti a 32 bit a causa del numero maggiore di registri nel modello a 64 bit, quindi, se possibile, creare build a 64 bit.

E ovviamente dovresti anche profilare il tuo codice, in modo da sapere con certezza dove si trovano gli hotspot. Non dici quale sistema operativo utilizzi ma VTune su Windows, Zoom su Linux o Shark su Mac OS X ti aiuterà a trovare rapidamente e facilmente i colli di bottiglia delle tue prestazioni.

0

La macchina è ottimizzata per il punto mobile, quindi probabilmente non si risparmia molto andando alle frazioni a virgola fissa.

Tu dici che non c'è un singolo collo di bottiglia, ma potrebbero essercene multipli, e se riesci a radere uno di loro, gli altri prenderanno più percentuali del tempo rimanente, attirando la tua attenzione su di loro, così puoi raderti anche loro.

Probabilmente avete fatto questo, ma vorrei essere sicuro non solo che le funzioni dispendiose in termini di tempo siano il più veloci possibile, ma vengono chiamate non più del necessario.

+0

"... probabilmente non salverai molto andando alle frazioni a punto fisso." Avete riferimenti o esperienze di prima mano a sostegno di questo? – Thomas

+1

@Thomas: esperienza personale. Ho utilizzato le frazioni in virgola fissa in modo estensivo nella grafica prima che i processori FP fossero onnipresenti. Ero al Instrumentation Lab durante Apollo, quando l'intero sistema di navigazione era fatto con frazioni a virgola fissa. Ora con hardware FP su chip, in cui tutta la rilevazione di normalizzazione, aggiunta, moltiplicazione e NaN viene eseguita il più possibile in logica combinatoria a piena velocità di clock, suppongo, ma sospetto che la moltiplicazione e la divisione saranno nella stessa palla park, galleggiante vs punto fisso + cambio. –

Problemi correlati