2011-01-03 12 views
34

Sto leggendo "C++ accelerato". Ho trovato una frase che afferma "a volte double è più veloce in esecuzione di float in C++". Dopo aver letto la frase mi sono confuso su float e double funzionante. Per favore, spiegami questo punto.doppio o mobile, che è più veloce?

+6

Quasi uguale a: http://stackoverflow.com/questions/417568/float-vs-double-performance –

+0

@Devendra: Questo è C#, non C++. – AbdullahC

+4

Se stai leggendo "C++ accelerato", l'ultima cosa di cui dovresti preoccuparti è quale tipo è più veloce - concentrati sui concetti e quando hai un problema reale, quindi preoccupati ... – Nim

risposta

38

Dipende da cosa fa l'hardware nativo.

  • Se l'hardware implementa doppia (come x86 fa), quindi galleggiante viene emulato estendendolo lì, e la conversione costerà tempo. In questo caso, il doppio sarà più veloce.

  • Se l'hardware implementa solo float, l'emulazione double con esso costerà ancora più tempo. In questo caso, float sarà più veloce.

  • E se l'hardware non implementa nessuno, ed entrambi devono essere implementati nel software. In questo caso, entrambi saranno lenti, ma il doppio sarà leggermente più lento (più carico e operazioni di archiviazione per lo meno).

La citazione si parla probabilmente si riferisce alla piattaforma x86, in cui il primo caso era dato. Ma questo non è vero in generale.

+18

AFAIK x86 ha effettivamente registri a 80 bit, non float né doppi. – ybungalobill

+0

Inoltre, dipende dalla quantità di dati che si sta elaborando. Con matrici o matrici di grandi dimensioni, la cache può iniziare a influire sulle prestazioni. –

+0

@Bart, ho fatto test prima e fondamentalmente il doppio tende a vincere contro float, anche con grandi set di dati. Se vuoi essere sicuro di dover fare un benchmark, ma in pratica galleggia raramente vince su x86. –

23

È possibile trovare una risposta completa su questo articolo

What Every Computer Scientist Should Know About Floating-Point Arithmetic

Questa è una citazione da un precedente Discussione Stack Overflow di float x doppio per quanto riguarda Memory Bandwidth

Se un doppio richiede più spazio di un float, quindi impiegherà più tempo per leggere i dati. Questa è la risposta ingenua. Su un moderno IA32, tutto dipende da dove provengono i dati . Se è nella cache L1, il carico è trascurabile, a condizione che i dati provengano da una singola riga della cache. Se si estende su più di una linea di cache , c'è un piccolo sovraccarico. Se è da L2, ci vuole un po 'di più, se è nella RAM, allora è ancora più lungo e infine, se è su disco è un enorme tempo . Quindi la scelta di float o double è meno importante del modo in cui vengono utilizzati i dati . Se si desidera eseguire un piccolo calcolo su molti dati sequenziali , è preferibile un tipo di dati di piccole dimensioni. Fare un sacco di calcoli su un piccolo insieme di dati consentirebbe di utilizzare i tipi di dati più grandi con un significativo effetto . Se accedete ai dati in modo molto casuale, la scelta dei dati della dimensione non è importante - i dati vengono caricati in pagine/linee cache. Pertanto, anche se si desidera un solo byte dalla RAM , è possibile trasferire 32 byte (questo è molto dipendente dall'architettura del sistema ). Oltre a tutto ciò, la CPU/FPU potrebbe essere super-scalare (ovvero pipelined). Così, anche se un carico può richiedere diversi cicli, la CPU/FPU potrebbe essere occupato a fare qualcos'altro (un moltiplicare per esempio) che nasconde il tempo carico in misura

+0

+1 per il collegamento all'articolo :-) – Nawaz

+0

+1 da parte mia anche per quel collegamento. – foo

3

mi viene in mente due casi di base quando doppie sono più veloci di carri:

  1. L'hardware supporta doppie operazioni ma non galleggiare operazioni, in modo da carri saranno emulate dal software e quindi essere più lento.

  2. Hai davvero bisogno della precisione dei doppi. Ora, se usi float in ogni caso dovrai usare due float per raggiungere una precisione simile al doppio. L'emulazione di un vero doppio con float sarà più lenta rispetto all'utilizzo di float in primo luogo.

    1. Non è necessario il doppio, ma l'algoritmo numerico converge più velocemente grazie alla maggiore precisione dei doppi. Inoltre, i doppi potrebbero offrire una precisione sufficiente per utilizzare un algoritmo più veloce ma numericamente meno stabile.

Per completezza amor Ho anche dare alcune ragioni per il caso opposto di carri essere più veloce. Si può vedere di persona whichs motivi dominano nel tuo caso:

  1. galleggianti sono più veloce di doppie quando non hai bisogno di doppia precisione e vi sono la memoria-bound larghezza di banda e l'hardware non comportano una pena su galleggianti.

  2. Essi conservano la larghezza di banda della memoria perché occupano metà spazio per numero.

  3. Esistono anche piattaforme in grado di elaborare più float del doppio in in parallelo.

+0

Poiché sto ripetutamente ottenendo downvotes non commentati, ho deciso di modificare la mia risposta. La nuova roba è nella prima parte della risposta. –

1

float è in genere più veloce. il doppio offre una maggiore precisione. Tuttavia, in alcuni casi le prestazioni possono variare se vengono utilizzate estensioni speciali del processore come 3dNow o SSE.

3

Su Intel, il coprocessore (al giorno d'oggi integrato) gestirà entrambi allo stesso modo, ma come altri hanno notato, i doppi generano una maggiore larghezza di banda di memoria che può causare colli di bottiglia. Se si utilizzano istruzioni SSE scalari (predefinite per la maggior parte dei compilatori su 64 bit), lo stesso vale. Quindi, generalmente, a meno che tu non stia lavorando su un grande insieme di dati, non importa molto.

Tuttavia, le istruzioni SSE parallele consentiranno di gestire quattro float in un'unica istruzione, ma solo due in doppio, quindi in questo modo il float può essere notevolmente più veloce.

8

Risposta breve è: dipende.

La CPU con x87 creerà i galleggianti e raddoppia altrettanto velocemente. Il codice Vectorized verrà eseguito più velocemente con i float, perché SSE può eseguire il crunch di 4 float o 2 doppi in un solo passaggio.

Un'altra cosa da considerare è la velocità della memoria. A seconda dell'algoritmo, la CPU potrebbe essere inattiva molto durante l'attesa dei dati. Il codice intensivo di memoria trarrà vantaggio dall'uso di float, ma il codice ALU limitato non lo farà (a meno che non sia vettorializzato).

2

C'è solo una ragione galleggianti 32 bit possono essere più lenta doppie 64 bit (o 80 bit 80x87). E questo è l'allineamento. Oltre a questo, i float occupano meno memoria, generalmente con un accesso più veloce, migliori prestazioni della cache. Richiede anche meno cicli per elaborare le istruzioni a 32 bit. E anche quando (co) -processore non ha istruzioni a 32 bit, può eseguirle su registri a 64 bit con la stessa velocità. Probabilmente è possibile creare un caso di test in cui i doppi saranno più veloci dei float e v.v., ma le mie misurazioni di algos statistiche reali non hanno mostrato differenze evidenti.

+0

Sembra che tu pensi che l'accesso alla memoria non costerebbe tempo. Ma dalla mia esperienza (e dai fogli dati di tutto l'hardware che ho visto) lo fa. – foo

2

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.

+1

bene speriamo per il meglio allora –

+0

Double aveva una precisione più elevata che fluttua e usa più memoria raddoppia 8 byte e float 4 byte. Il più veloce è fluttuante attraverso la scrittura della memoria.Non so come sia il tuo test, ma i tempi sono rumorosi. –

Problemi correlati