2013-02-28 17 views
9

L'FPU x87 è notevole per l'utilizzo di una modalità di precisione interna a 80 bit, che spesso porta a risultati imprevisti e non riproducibili tra compilatori e macchine. In my search per la matematica in virgola mobile riproducibile su .NET, ho scoperto che entrambe le principali implementazioni di .NET (Microsoft e Mono) emettono istruzioni SSE piuttosto che x87 in modalità 64 bit.L'aritmetica in virgola mobile SSE è riproducibile?

SSE (2) utilizza registri rigorosamente a 32 bit per float a 32 bit e registri rigorosamente a 64 bit per float a 64 bit. I denormali possono facoltativamente essere azzerati impostando lo appropriate control word.

Sembra quindi che SSE non soffra dei problemi di precisione di x87 e che l'unica variabile è il comportamento denormale, che può essere controllato.

Lasciando da parte la questione delle funzioni trascendentali (che non sono fornite in modo nativo da SSE a differenza di x87), l'uso di SSE garantisce risultati riproducibili su macchine e compilatori? Le ottimizzazioni del compilatore, ad esempio, potrebbero tradursi in risultati diversi? Ho trovato alcuni pareri contrastanti:

Se avete SSE2, usarlo e vivere felici e contenti. SSE2 supporta entrambe le operazioni 32b e 64b ei risultati intermedi sono della dimensione degli operandi. - Yossi Kreinin, http://www.yosefk.com/blog/consistency-how-to-defeat-the-purpose-of-ieee-floating-point.html

...

Le istruzioni SSE2 (...) sono pienamente compatibili IEEE754-1985, e permettere una migliore riproducibilità (grazie all'arrotondamento statica precisione) e portabilità con altre piattaforme. Muller et aliis, Handbook of Floating-Point Arithmetic - p.107

però:

Inoltre, non è possibile utilizzare SSE o SSE2 per virgola mobile, perché è troppo sotto-specificato di essere deterministico . - John Watte http://www.gamedev.net/topic/499435-floating-point-determinism/#entry4259411

+1

Sono abbastanza sicuro che se ci sono due opinioni contrastanti sul web, otterrete un argomento qui (e probabilmente anche un terzo parere) – KevinDTimm

+1

@KevinDTimm che non rende questa domanda soggettiva. SSE è riproducibile o non lo è. – Asik

+1

"SSE o SSE2 [è] troppo sotto specificato per essere deterministico". Non pretendo di essere un esperto su questi argomenti, ma questo mi sembra un errore. Nel link si parla di funzioni di libreria per trascendentale e naturalmente potrebbero esserci bug in quelli su una piattaforma e non un'altra come in effetti potrebbe esserci (anzi, probabilmente lo è) nell'ottimizzatore di qualsiasi compilatore, ma ciò non dice nulla su SSE/SSE2 di per sé. Ha un esempio di ciò che intende? –

risposta

9

SSE è completamente specificato *. Muller è un esperto in aritmetica in virgola mobile; a chi ti fiderai, lui o qualcuno in un forum di gamedev?

(*) ci sono in realtà alcune eccezioni per operazioni non IEEE-754 come rsqrtss, dove Intel non ha mai completamente specificato il comportamento, ma ciò non influisce sulle operazioni di base IEEE-754, e ancora più importante il loro comportamento può A questo punto, in realtà, cambieranno perché comprometterebbe la compatibilità binaria per troppe cose, quindi sono buone come specificato.

3

Come notato da Stephen, i risultati prodotti da un dato pezzo di codice assembly SSE saranno riproducibili; si alimenta lo stesso codice con lo stesso input e alla fine si ottiene lo stesso risultato. (Cioè, la citazione di John Watte è completamente sbagliata.)

Hai buttato lì la parola "compilatori", però. Questo è un gioco di palla completamente diverso. Molti compilatori sono ancora piuttosto cattivi nel preservare la correttezza del codice a virgola mobile.(The ATLAS errata page fa menzione che clang "non riesce a produrre codice corretto per alcune operazioni.") Se si utilizzano funzioni speciali nel codice, si è anche, in una certa misura, in balia di chiunque abbia implementato la libreria matematica.