Devo ancora utilizzare il punto fisso per garantire che i computer ottengano più lo stesso risultato per le operazioni matematiche?


9

Mi è stato detto che la maggior parte dei computer moderni segue lo stesso standard in virgola mobile, significa che avranno tutti la stessa risposta mobile per una determinata operazione matematica se gli input sono uguali?

Lo chiedo perché sto cercando di realizzare un gioco RTS su una rete e la sincronizzazione di centinaia di posizioni dell'unità sembra una brutta strada da percorrere.

Quindi, se invio solo input, devo garantire a tutti i clienti di ottenere lo stesso risultato facendogli eseguire la simulazione da quegli input.

Ho letto che i vecchi giochi RTS usavano l'aritmetica a virgola fissa, ma non so se ciò sia ancora richiesto sui computer moderni se aderiscono tutti allo stesso standard? Mi è stato anche detto che, sebbene impreciso, il risultato del virgola mobile è deterministico per lo stesso input (che presumo significhi che qualsiasi computer che segue lo stesso standard ottiene lo stesso risultato impreciso?).

I computer hanno ancora deviazioni anche se seguono lo stesso standard in virgola mobile?

Sto scrivendo questo gioco in C # non sono sicuro che sia importante, ho pensato di menzionarlo comunque.


Anche se lo facessero, non
userei i

Cosa intendi ? Perchè no?
WDUK,

L'uso di galleggianti può essere indesiderabile comunque perché il comportamento potrebbe dipendere dalla posizione sulla mappa. Le terre lontane di Minecraft erano un esempio notevole: il movimento, il rendering e la generazione del terreno diventavano glitch quando ti allontanavi dal punto di spawn.
am

Risposte:


18

I computer hanno ancora deviazioni anche se seguono lo stesso standard in virgola mobile?

Sfortunatamente sì, specialmente quando usi C # (o un altro linguaggio compilato JIT). Il problema che si verifica qui è che la fase di compilazione JIT su alcune architetture di processori produce codice che utilizza più registri CPU rispetto ad altre architetture. Ciò può portare a situazioni in cui su alcune macchine viene utilizzata la precisione in virgola mobile estesa per determinate operazioni, mentre su altre macchine no. Ciò significa che per ogni calcolo iterativo che utilizza i doppi, esiste la possibilità di produrre diversi errori di arrotondamento accumulati.

Non è un problema ipotetico, ho esperienza diretta con tali deviazioni nel software di simulazione ingegneristica contemporanea, su hardware più o meno moderno. Questo problema rende davvero difficile creare test di regressione affidabili per calcoli complessi in virgola mobile che producono esattamente lo stesso risultato su tutte le macchine coinvolte.


Questo. Alcune cause alla radice: IEEE Std 754 include clausole "should" facoltative (ad es. Gestione di NaN) e consente alternative di progettazione (ad es. Rilevamento di underflow). Nella misura in cui i binding di linguaggio supportano lo standard in virgola mobile, possono comunque lasciare spazio al compilatore durante la valutazione delle espressioni in virgola mobile, ad esempio FLT_EVAL_METHODin ISO C / C ++. Le funzioni trascendentali (ad es sin. exp, log) Non sono ampiamente regolate né dallo standard IEEE in virgola mobile né dagli standard del linguaggio di programmazione. Un semplice aggiornamento della versione della libreria (ad es. Una nuova glibcversione) potrebbe causare risultati diversi.
njuffa,

L'ho colpito da solo in un gioco. Il razzo volò bene sul mio laptop, non volerebbe sul mio desktop, installazioni completamente identiche.
Loren Pechtel,

3

Errori in virgola mobile

Ogni numero in virgola mobile accumula imprecisione mentre viene utilizzato per il calcolo. Questo è un semplice fatto dell'uso di un formato impreciso per il calcolo. I calcoli sono anche sensibili all'ordine di calcolo, la commutatività non è garantita, ovvero: (a + b) + cpuò o meno essere uguale a a + (b + c).

Inoltre i processori non hanno necessariamente la stessa lunghezza della mantissa dello standard di memoria. Ciò può generare un comportamento interessante poiché il float a 32/64/128 bit occasionalmente funziona come se avesse più bit.

Errori a virgola fissa

Detto questo, l'aritmetica a virgola fissa può anche accumulare errori. La differenza è che i numeri a virgola fissa sono chiari su quale precisione si perde e, a seconda delle operazioni scelte, è possibile evitare del tutto errori di arrotondamento. Sono anche commutativi (a + b) + c = a + (b + c).

Quale?

Quale utilizzare dipende interamente da quali proprietà sono necessarie.

Numeri in virgola mobile:

  • dare una vasta gamma di valori che diventano molto fini a grana ravvicinata e progressivamente più distanti agli estremi.
  • sono sensibili all'ordine di calcolo
  • accumulare errori di arrotondamento nel tempo.
  • può avere un comportamento irregolare a causa della mancata corrispondenza della dimensione del float hardware / memoria.

Numeri a punto fisso:

  • dare un intervallo più piccolo di numeri con la stessa distanza tra due numeri consecutivi.
  • sono meno sensibili all'ordine di calcolo
  • sono più chiari sugli errori di arrotondamento
  • può essere lavorato per minimizzare / evitare problemi di arrotondamento.

1
"i numeri in virgola fissa sono chiari su quale precisione si perde" - anche i punti in virgola mobile sono chiari, la differenza è piuttosto che le imprecisioni in punti fissi sono più intuitive rispetto alla numerazione ordinaria della vita
whatsisname

1
Quindi solo il punto fisso garantisce che tutti i computer indipendentemente dall'hardware ecc. Subiranno gli stessi errori / perdite di precisione?
WDUK,

1
In sostanza, sì, perché puoi specificare che i tuoi numeri a virgola fissa sono 32 o 64 bit e saranno su tutti i sistemi. I numeri in virgola mobile possono essere 32 o 64 bit, ma l'hardware può effettivamente utilizzare 48 o 96 bit per eseguire il calcolo e convertirlo in 32 o 64 bit alla fine con conseguente differenza tra i diversi tipi di hardware.
user1118321

@whatsisname Mentre le specifiche in virgola mobile sono abbastanza chiari, non si può facilmente dirmi cosa arrotondamento problemi farò incontrare in questa somma: (a + b * c) / d - e. Ad eccezione di ovvi problemi come NaN, divisione per zero o overflow / underflow è possibile che questa espressione sia errata. Aggiungete a ciò l'impedenza tra memoria e registro in termini di precisione e anche un semplice carico / archivio dalla memoria dello "stesso" valore in virgola mobile cambierà la risposta.
Kain0_0 il

@ Kain0_0: hai ragione, non posso dirti facilmente cosa incontrerò, perché non sono un esperto in virgola mobile. Questo è esattamente ciò che si intende quando ho detto "più intuitivo alla numerazione della vita ordinaria". Quando dici che il punto fisso è "chiaro" e il virgola mobile non lo è, lo fai sembrare come se i galleggianti fossero solo apparentemente casualmente inaccurati.
whatsisname

-1

C'è la domanda sul motivo per cui vorresti garantire risultati identici, dal momento che risultati identici non garantiscono affatto che i tuoi risultati siano utili .

Si potrebbe avere un algoritmo numericamente instabile che fornisce due risultati identici ma completamente privi di senso in computer diversi. Se ci sono differenze, ma i risultati sono gli stessi entro 13 cifre, è molto più affidabile.

Esistono pochissime situazioni in cui la riproducibilità è davvero importante: in un motore di layout o compressione / decompressione senza perdita di dati. È molto probabile che l'utilizzo del punto fisso non sia corretto.


Non ho declassato la tua risposta, ma sembra che il caso descritto dall'OP sia esattamente "una di quelle poche situazioni in cui la riproducibilità è davvero importante". In un gioco RTS, un piccolo errore di arrotondamento può fare la differenza tra "due oggetti scontrati" o meno.
Doc Brown,
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.