Prestazioni e altri problemi nell'utilizzo di tipi in virgola mobile in C ++

5

Essendo interessato alla programmazione delle prestazioni in C ++, c'è un aspetto di cui non ho davvero idea - e questo è il significato dell'uso di calcoli in virgola mobile contro il doppio rispetto alla matematica normale intera?

Quali problemi di prestazioni con questi tipi di calcoli dovrei prendere in considerazione? Quali altri aspetti devono essere considerati al momento di decidere quale tipo di operatori utilizzare?

Tutto quello che attualmente so è che i doppi sono probabilmente i più costosi perché sono più grandi, il punto mobile è successivo e quindi i calcoli su interi sono solitamente i più veloci su una CPU perché sono molto più semplici.

    
posta user997112 12.03.2013 - 22:59
fonte

2 risposte

7

I commenti di @ratchet, @Sjoerd e @Stephane rispondono alla domanda.

La tua affermazione nella domanda "Tutto quello che so attualmente è che i doppi sono probabilmente i più costosi perché sono più grandi" mostra le regole sull'ottimizzazione - sono vere - "Solo per esperti" seguito dal "Non sei ancora un esperto" .....

A meno che tu non conosca i minimi dettagli dell'hardware sottostante E come il compilatore li usi, non puoi fare affermazioni sui numeri in virgola mobile. Non si può nemmeno essere certi che un'operazione in virgola mobile richieda più tempo di un'operazione intera. Di norma, ci sono abbastanza problemi con i programmatori che scrivono correttamente il codice in virgola mobile, che dovrebbe essere evitato a meno che non sia necessario. Se necessario, le prestazioni sono di scarsa importanza.

Come regola generale - usa gli Ints se possibile - raramente è più lento delle operazioni FP, e spesso più veloce e più prevedibile. Se devi usare le operazioni FP, usa il doppio. I galleggianti non hanno una mantissa abbastanza grande per qualsiasi cosa tranne il più duro dei calcoli (a meno che non si prenda estrema cura) e un incline agli errori di arrotondamento insidiosi.

Tuttavia, come tutte le regole empiriche, devono essere applicate in modo appropriato. Se è importante, misuralo.

    
risposta data 13.03.2013 - 01:16
fonte
1

Utilizza lo strumento giusto per il lavoro

Ricorda la vecchia sega sull'uomo che aveva solo un martello?

Ci sono molti numeri interi e molti tipi in virgola mobile e ci sono molte implementazioni per loro. Se li conosci bene, renderà i tuoi risultati migliori, per non parlare del tuo codice. Quando fai le tue scelte, utilizzerai diversi criteri.

Applicazioni

Se la tua applicazione utilizza fondamentalmente numeri interi, generalmente usa numeri interi. In C ++ avete entrambi firmato (predefinito) e non firmato, e selezionando unsigned non solo vi darete quasi il doppio del limite massimo, potrebbe permettere al compilatore di avvertirvi su usi impropri del vostro numero.

Se usa valori decimali, spesso una rappresentazione a virgola mobile può essere migliore. Innanzitutto, può essere più naturale programmare un'equazione da scienza, ingegneria o azienda quando i valori non sono limitati a numeri interi. Il decimale codificato in formato binario (BCD) può anche aiutare con la valuta e, sebbene richieda più spazio e sia più lento, ha alcune caratteristiche desiderabili se usato in modo appropriato.

Se l'applicazione si riferisce alla valuta, potrebbe essere complicata perché il virgola mobile non è preciso, quindi occasionalmente puoi guadagnare o perdere centesimi a causa degli arrotondamenti. A volte è possibile manipolare in centesimi interi anziché in virgola mobile per accelerare le cose e renderle più precise.

Preferisci doppio al float

In genere preferisco il doppio al float perché sono meno propensi a introdurre errori di arrotondamento. Il compilatore C ++ spesso promuove i float per raddoppiare mentre li passa alle funzioni di libreria standard anche per i calcoli con gli operatori di base. L'uso dei doppi generalmente rende il tuo codice e il codice macchina generato dal compilatore un po 'meno complicato.

L'arrotondamento molto frequente può diventare un problema, quindi dovrai considerare le conversioni tra intero e virgola mobile, sequenza di valutazione all'interno di equazioni, errori accumulati all'interno di cicli e normalizzazione di valori molto grandi e molto piccoli quando usati insieme. Avrai voglia di validare gli intervalli di input e output, e talvolta i valori intermedi per assicurare che le cose non siano andate storte.

Dimensioni importa

Per assicurare che i risultati abbiano valori precisi, potrebbe essere necessario comprendere l'intervallo e la rappresentazione dei tipi a virgola mobile e un po 'di analisi numerica. Il link ha molte informazioni interessanti.

Poiché un altro voto negativo per i float a favore dei doppi considera che un float a 32 bit masterizzerà otto bit per l'esponente e la parte mantissa che contiene una versione ridimensionata del tuo valore dovrà adattarsi a 23 bit dopo l'account per il segno della mantissa. 2 ^ 23 non è particolarmente grande. Se vuoi contare da uno a 10 milioni, potresti voler usare un intero a 32 bit o un doppio.

Architettura sottostante

Se hai un hardware in virgola mobile, generalmente è OK usarlo. In caso contrario, le librerie altamente ottimizzate su processori con fix point a clock veloce potrebbero ancora far fronte molto bene.

Se hai un cavallo da lavoro a otto bit, impara come ridimensionare e normalizzare gli input e con tutti i mezzi, attuare attentamente i tuoi calcoli ripetitivi e dispendiosi in termini di tempo utilizzando il punto fisso. Sono un fan della documentazione di Arduino, anche se il mio gusto è usare hardware più robusto quando lavoro su sistemi embedded. Il seguente link ha una buona discussione su cosa fare quando il tuo ambiente non ha un punto di virgola mobile nativo e il tuo compilatore ti dà solo i float (ma non i doppi).

link

Molte architetture orientate ai punti fissi (ad esempio, alcuni processori di segnali digitali (DSP)) possono aiutarti con istruzioni hardware come moltiplicare - accumulare e spesso includono istruzioni molto utili per aiutare a moltiplicare o effettuare spostamenti aritmetici usando interi. I dettagli per l'utilizzo di questi possono essere eseguiti dal compilatore o dalle librerie, quindi vale la pena di imparare il più possibile sul processore, in particolare se lavori su DSP o progetti integrati.

    
risposta data 15.03.2013 - 05:43
fonte

Leggi altre domande sui tag