Float, double o entrambi per la classe Vector 2D?


11

Attualmente sto scrivendo un piccolo motore di gioco 2D basato su OpenGL multipiattaforma per il nostro studio. Quando ho cercato quale classe di vettore 2D usare, mi sono imbattuto in tre diversi paradigmi di progettazione:

  • Float & Call-by-value, come in questo articolo Gamasutra . Sembra essere veloce ma offre poca precisione (vedi anche questa discussione ). Pro: veloce, portatile e compatibile con la maggior parte delle librerie.

  • Doppio e chiamata per riferimento. Se capisco bene l'articolo sopra, potrei anche usare 2 variabili a doppia precisione invece dei 4 numeri float. Secondo il thread sopra il doppio è ancora più lento del float.

  • Template per double e float: il popolare libro " Game Engine Architecture " utilizza i template per rendere possibile l'uso di float e double in base alle esigenze. L'ovvio inconveniente è il bloat del codice. Inoltre, dubito che il codice possa essere ottimizzato senza fondamentalmente scrivere due classi, comunque.

Gradirei sapere quali soluzioni stai usando nei tuoi motori interni e quanto sono precisi, ad esempio, i motori di gioco più diffusi, così posso decidere quale soluzione implementerò nel nostro motore. Al momento sto pensando di usare semplicemente la precisione del galleggiante e conviverci.


Più lento dove ? Non puoi parlare di velocità se non è legato a una particolare architettura.
o0 '.

2
@ Lo'oris: non conosco alcuna architettura in cui il doppio è più veloce del float.

Invece di scrivere la tua classe vettoriale, considera l'utilizzo di Sony ( bulletphysics.org/Bullet/phpBB3/… ). È una semplice "libreria" solo intestazione drop-in che è già stata micro-ottimizzata e tutte le librerie vettoriali sono comunque sostanzialmente la stessa interfaccia esterna.

@Joe: 2 doppie invece di 4 galleggianti?
o0 '.

@ Lo'oris: la domanda è un po 'strana, non so se l'interrogatore è confuso o solo tu - usi due doppi "invece di" quattro float quando hai a che fare con SIMD, perché il registro è largo 128 bit. Devi ancora elaborare un numero uguale di numeri e lo stai facendo a metà velocità.

Risposte:


9

Uso sempre float a meno che non abbia un motivo per usare double, tanto quanto uso int a meno che non abbia un motivo per usare int64_t.

I float non hanno problemi a eseguire l'aritmetica di interi interi fino a 2 24 , che è ciò di cui la maggior parte delle persone (per lo più irrazionalmente) ha paura. I doppi non risolvono esattamente il problema dei valori comuni che non sono rappresentabili esattamente: se ottieni 0,10000001 o 0,1000000000000000001, devi comunque assicurarti che il tuo codice lo consideri "uguale" a 0,09999999.

I doppi sono più lenti su ogni piattaforma di cui ti occuperai a scrivere giochi, occupano il doppio della larghezza di banda della memoria e hanno meno istruzioni specializzate sulla CPU disponibili.

I float a precisione singola rimangono lo standard per le interfacce grafiche hardware, sia sul lato C / C ++ che all'interno degli shader.

Probabilmente avrai bisogno di un doppio vettore ad un certo punto, ma dovrebbe essere usato quando necessario, non per impostazione predefinita.

Per quanto riguarda il templating: hai ragione, per ottenere le massime prestazioni dovrai comunque specializzare i modelli manualmente. A parte questo, ho eseguito alcuni test per alcuni codici modello durante il fine settimana (creando un IntRect e FloatRect a 4 pagine), e ho scoperto che la versione basata su modelli richiedeva circa 20 volte più tempo per essere compilata rispetto alla semplice ripetizione del codice, che ammontava a circa 15 righe . La ripetizione fa schifo, ma aspettare la compilazione fa più schifo - e non è che avrò mai bisogno di StringRect o FooRect.


"I doppi sono più lenti su ogni piattaforma [...] " - Citazione necessaria.
Zenith,

3

Il framework di gioco Microsoft XNA ha una classe Vector2 che utilizza float. Questa sarebbe la mia più grande ragione personale per andare con i galleggianti, poiché mi fido che la saggezza e l'esperienza del team XNA siano molto più grandi delle mie.

Ho trovato piuttosto interessante leggere la risposta in questa domanda Stack Overflow: "Float vs Double Performance" . C'è anche un thread di gamedev.net con alcune discussioni sulle doppie prestazioni nelle GPU. Penso che sia sicuro presumere che i doppi siano più lenti dei float, almeno in molte GPU, e personalmente ho sempre usato le funzioni float OpenGL sulle loro doppie controparti. Questo potrebbe non essere valido al giorno d'oggi, ma se si considera che non tutti coloro che eseguono il gioco hanno l'ultima GPU con doppio supporto nativo, penso che questo sia un motivo sufficiente per usare i float e ottenere quel po 'di prestazioni extra.


1
Dalla domanda SO: "Sui processori x86, almeno, float e double saranno convertiti ciascuno in un reale a 10 byte dall'FPU per l'elaborazione." Sebbene ciò sia vero, trascura sia le istruzioni SIMD sia i requisiti di memoria aggiuntiva (= peggior coerenza della cache, maggiore larghezza di banda della memoria) dei doppi, entrambi i quali continuano a renderlo più lento rispetto al float nei test del mondo reale.

Ho pensato che ci fosse un trucco. Dovresti commentarlo sulla risposta SO, la voterei.
Ricket,

È già lì come commento.

1
Da quando hai allevato XNA, posso anche sottolineare che Direct2D utilizza anche float a precisione singola.
Mike Strobel,

E per completezza, OpenGL ha float e doppie versioni dei suoi metodi, quindi è neutro in questo senso.
Ricket,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.