2010-08-06 6 views
51

I valori doppi memorizzano maggiore precisione e raddoppiano le dimensioni di un float, ma le CPU Intel sono ottimizzate per i float?usa il doppio più veloce del float?

Cioè, le doppie operazioni sono altrettanto veloci o più veloci delle operazioni flottanti per +, -, * e /?

La risposta cambia per architetture a 64 bit?

+0

Dipende da ciò che si sta facendo con loro. In teoria, la larghezza di banda della memoria potrebbe entrare in essa. Hai altre informazioni? –

risposta

61

Non c'è una singola "CPU Intel", soprattutto in termini di operazioni ottimizzate rispetto ad altre !, ma la maggior parte di esse, a livello di CPU (specificamente all'interno della FPU), sono tali che la risposta a la tua domanda:

sono doppie operazioni altrettanto veloce o più veloce di operazioni galleggiante per +, -, * , e /?

è "sì" - all'interno della CPU. Tuttavia, il, occupando il doppio della memoria per ciascun numero implica chiaramente un carico maggiore sulla cache (s) e più larghezza di banda della memoria per riempire e versare quelle linee cache da/verso la RAM; il tempo che ti interessa delle prestazioni di un'operazione in virgola mobile è quando esegui un lotto di tali operazioni, quindi le considerazioni sulla memoria e sulla cache sono cruciali.

@ risposta di Richard sottolinea che ci sono anche altri modi per eseguire operazioni FP (le istruzioni SSE; buon vecchio MMX era interi-only), particolarmente adatto per semplici ops sulla grande quantità di dati ("SIMD", singola istruzione/dati multipli) in cui ogni registro può contenere 4 float a precisione singola o solo 2 a precisione doppia, quindi questo effetto sarà ancora più marcato.

Alla fine, si ha a punto di riferimento, ma la mia previsione è che per ragionevoli (cioè grandi ;-) benchmark, troverete vantaggio di attaccare con precisione singola (assumendo, naturalmente, che si don' t necessario i bit di precisione in più! -).

+1

Ciò dipenderà anche dalla dimensione del blocco della cache, corretta? Se la tua cache recupera blocchi a 64 bit o più grandi, allora un double sarebbe altrettanto efficiente (se non più veloce) di un float, almeno per quanto riguarda le letture/scritture di memoria. –

+3

@Razor Se lavori esattamente come molti float che si adattano a una linea di cache, se invece utilizzi il doppio invece la CPU dovrà recuperare due linee di cache. L'effetto di memorizzazione nella cache che avevo in mente quando ho letto la risposta di Alex è comunque: il tuo set di float si adatta alla tua cache di nth level ma il corrispondente set di double non lo fa.In questo caso, se utilizzi i galleggianti, aumenterai notevolmente le prestazioni. –

+0

@Peter, sì, ha senso, diciamo che hai una cachelina a 32 bit, l'uso del doppio dovrebbe essere recuperato due volte ogni volta. –

5

L'unica risposta veramente utile è: solo tu puoi dirlo. Devi fare un benchmark dei tuoi scenari. Piccoli cambiamenti nelle istruzioni e nei modelli di memoria potrebbero avere un impatto significativo.

Sarà sicuramente importante se si utilizza l'hardware di tipo FPU o SSE (prima fa tutto il suo lavoro con 80 ma la precisione estesa, quindi il doppio sarà più vicino, più tardi sarà 32bit nativo, cioè float).

Aggiornamento: s/MMX/SSE/come indicato in un'altra risposta.

2

Il punto mobile è normalmente un'estensione della CPU di uso generale. La velocità dipenderà quindi dalla piattaforma hardware utilizzata. Se la piattaforma ha supporto in virgola mobile, sarei sorpreso se c'è qualche differenza.

21

Se tutti i calcoli in virgola mobile vengono eseguite all'interno della FPU, quindi, non v'è alcuna differenza tra un calcolo double e un calcolo float perché le operazioni in virgola mobile sono eseguiti con 80 bit di precisione nella pila FPU. Le voci dello stack FPU vengono arrotondate come appropriato per convertire il formato in virgola mobile a 80 bit nel formato double o float in virgola mobile. Lo spostamento di sizeof(double) byte a/da RAM rispetto a sizeof(float) byte rappresenta l'unica differenza di velocità.

Se, tuttavia, si dispone di un calcolo vettoriale, è possibile utilizzare le estensioni SSE per eseguire quattro calcoli float nello stesso momento di due calcoli double. Pertanto, l'uso intelligente delle istruzioni SSE e dei registri XMM può consentire un maggiore throughput su calcoli che utilizzano solo float s.

7

Un altro punto da considerare è se si utilizza GPU (la scheda grafica). Lavoro con un progetto che è intensivo numericamente, ma non abbiamo bisogno della percisione che raddoppia. Utilizziamo le schede GPU per accelerare ulteriormente l'elaborazione. Le GPU CUDA hanno bisogno di un pacchetto speciale per supportare il doppio e la quantità di RAM locale su una GPU è abbastanza veloce, ma piuttosto scarsa. Di conseguenza l'uso di float raddoppia anche la quantità di dati che possiamo memorizzare su

Un altro punto è la memoria. I float prendono la metà della RAM dei doppi. Se hai a che fare con set di dati MOLTO grandi, questo può essere un fattore molto importante. Se si usa il doppio significa che si deve eseguire il cache su disco rispetto a ram puro, la differenza sarà enorme.

Quindi per l'applicazione con cui sto lavorando, la differenza è piuttosto importante.

9

In esperimenti di aggiunta di 3,3 per 2000 milioni di volte, i risultati sono:

Summation time in s: 2.82 summed value: 6.71089e+07 // float 
Summation time in s: 2.78585 summed value: 6.6e+09 // double 
Summation time in s: 2.76812 summed value: 6.6e+09 // long double 

Così il doppio è più veloce e di default in C e C++. È più portatile e il valore predefinito su tutte le funzioni di libreria C e C++. Alos double ha una precisione significativamente maggiore rispetto al float.

Anche Stroustrup raccomanda doppio nel corso del galleggiante:.

"L'esatto significato di singole, doppie, ed esteso precisione è definito dall'implementazione scelta del giusto di precisione per un problema in cui le questioni di scelta richiede notevole comprensione calcolo a virgola mobile Se non hai questa comprensione, ricevi consigli, prenditi il ​​tempo per imparare o usa il doppio e spera per il meglio. "

Forse l'unico caso in cui è necessario utilizzare float anziché double è su hardware a 64 bit con un moderno gcc. Perché float è più piccolo; double è 8 byte e float è 4 byte.

+3

+1 per fare lo sforzo di fare un po 'di tempo. Ma Stroustrup sconsiglia di usare 'double' perché è più veloce, ma a causa della precisione extra. Per quanto riguarda il tuo ultimo commento, se hai bisogno di quella precisione in più rispetto al risparmio di memoria, allora è abbastanza probabile che tu voglia usare "doppio" sull'hardware a 32 bit. E ciò riconduce alla domanda: il doppio è più veloce del float anche su hardware a 32 bit con una moderna FPU che esegue calcoli a 64 bit? –

+0

Alcuni centesimi di secondo fanno pensare che sia ancora nel regno dell'errore sperimentale. Soprattutto se ci sono anche altre cose (come forse un ciclo non srotolato ...). – imallett

+2

È un bel po 'dire che Stroustrup consiglia di "raddoppiarlo" quando in realtà lo consiglia a RTFM. – sunside

9

Voglio solo aggiungere alle grandi risposte già esistenti che la __m256? famiglia di persone dello stesso insegnamento-Multiple-dati (SIMD) C++ funzioni intrinseche operazione sulle siadouble s in parallelo (ad esempio _mm256_add_pd), oppure float s in parallelo (ad es. _mm256_add_ps).

Non sono sicuro se questo può tradursi in un vero e proprio velocità, ma sembra possibile elaborare 2x il maggior numero di carri da istruzioni quando si utilizza SIMD.