Regole a virgola mobile
Direct3D supporta diverse rappresentazioni a virgola mobile. Tutti i calcoli a virgola mobile operano in un sottoinsieme definito di regole a virgola mobile a precisione singola a 32 bit IEEE 754.
Regole a virgola mobile a 32 bit
Esistono due set di regole: quelli conformi a IEEE-754 e quelli che deviano dallo standard.
Regole IEEE-754 rispettate
Alcune di queste regole sono un'unica opzione in cui IEEE-754 offre scelte.
La divisione per 0 produce +/- INF, ad eccezione di 0/0 che restituisce NaN.
log di (+/-) 0 produce -INF.
il log di un valore negativo (diverso da -0) produce NaN.
Radice quadrata reciproca (rsq) o radice quadrata (sqrt) di un numero negativo produce NaN.
L'eccezione è -0; sqrt(-0) produce -0 e rsq(-0) produce -INF.
INF - INF = NaN
(+/-)INF / (+/-)INF = NaN
(+/-)INF * 0 = NaN
NaN (qualsiasi OP) qualsiasi valore = NaN
I confronti EQ, GT, GE, LT e LE, quando uno o entrambi gli operandi sono NaN restituisce FALSO.
I confronti ignorano il segno di 0 (quindi +0 è uguale a -0).
Il confronto NE, quando uno o entrambi gli operandi è NaN restituisce VERO.
I confronti di qualsiasi valore non NaN rispetto a +/- INF restituiscono il risultato corretto.
Deviazioni o requisiti aggiuntivi dalle regole IEEE-754
IEEE-754 richiede operazioni a virgola mobile per produrre un risultato che è il valore rappresentabile più vicino a un risultato infinitamente preciso, noto come il numero pari più vicino.
Direct3D 11 e up definiscono lo stesso requisito di IEEE-754: le operazioni a virgola mobile a 32 bit producono un risultato compreso tra 0,5 unità (ULP) del risultato infinitamente preciso. Ciò significa che, ad esempio, l'hardware è autorizzato a troncare i risultati a 32 bit anziché eseguire il numero pari più vicino, in quanto ciò comporta un errore di 0,5 ULP al massimo. Questa regola si applica solo all'aggiunta, alla sottrazione e alla moltiplicazione.
Le versioni precedenti di Direct3D definiscono un requisito più debole rispetto a IEEE-754: le operazioni a virgola mobile a 32 bit producono un risultato che si trova all'interno di un'unità ulP (1 ULP) del risultato infinitamente preciso. Ciò significa che, ad esempio, l'hardware è autorizzato a troncare i risultati a 32 bit anziché eseguire il numero pari più vicino, in quanto ciò comporta un errore di un ULP al massimo.
Non è disponibile alcun supporto per eccezioni a virgola mobile, bit di stato o trap.
I valori denormalizzati vengono scaricati per firmare lo zero mantenuto nell'input e nell'output di qualsiasi operazione matematica a virgola mobile. Le eccezioni vengono eseguite per qualsiasi operazione di I/O o di spostamento dati che non modifica i dati.
Gli stati che contengono valori a virgola mobile, ad esempio Viewport MinDepth/MaxDepth o BorderColor, possono essere forniti come valori denormalizzati e possono essere scaricati o meno prima che l'hardware li usi.
Le operazioni minime o massime eseguono lo svuotamento dei valori denormalizzati per il confronto, ma il risultato potrebbe essere o non essere Valore denormalizzato svuotato.
L'input NaN per un'operazione produce sempre NaN nell'output. Ma il modello di bit esatto del NaN non è necessario per rimanere invariato (a meno che l'operazione non sia un'istruzione di spostamento non elaborata, che non modifica i dati).
Le operazioni min o max per cui un solo operando è NaN restituiscono l'altro operando come risultato (contrariamente alle regole di confronto esaminate in precedenza). Si tratta di una regola IEEE 754R.
La specifica IEEE 754R per le operazioni min e max a virgola mobile indica che se uno degli input da min o max è un valore QNaN non interattiva, il risultato dell'operazione è l'altro parametro. Ad esempio:
min(x,QNaN) == min(QNaN,x) == x (same for max)
Una revisione della specifica IEEE 754R ha adottato un comportamento diverso per min e max quando un input è un valore SNaN di segnalazione rispetto a un valore QNaN:
min(x,SNaN) == min(SNaN,x) == QNaN (same for max)
In genere, Direct3D segue gli standard per l'aritmetica: IEEE 754R e IEEE-754R. Ma in questo caso, abbiamo una deviazione.
Le regole aritmetiche in Direct3D 10 e versioni successive non fanno alcuna distinzione tra valori NaN non interattiva e di segnalazione (QNaN e SNaN). Tutti i valori NaN vengono gestiti nello stesso modo. Nel caso di min e max, il comportamento Direct3D per qualsiasi valore NaN è simile al modo in cui QNaN viene gestito nella definizione IEEE-754R. Per completezza: se entrambi gli input sono NaN, viene restituito qualsiasi valore NaN.
Un'altra regola IEEE 754R è che min(-0,+0) == min(+0,-0) == -0 e max(-0,+0) == max(+0,-0) == +0, il che rispetta il segno, a differenza delle regole di confronto per lo zero firmato (come abbiamo visto in precedenza). Direct3D consiglia il comportamento di IEEE 754R, ma non lo applica. È consentito il risultato del confronto degli zeri in base all'ordine dei parametri, usando un confronto che ignora i segni.
x*1.0f restituisce sempre x (eccetto valore denormalizzato svuotato).
x/1.0f restituisce sempre x (eccetto valore denormalizzato svuotato).
x +/- 0.0f restituisce sempre x (eccetto valore denormalizzato svuotato). Ma -0 + 0 = +0.
Le operazioni di fusione (come mad, dp3) producono risultati che non sono meno accurati del peggior ordine di valutazione seriale possibile dell'espansione senza fusione dell'operazione. La definizione del peggior ordinamento possibile, allo scopo della tolleranza, non è una definizione fissa per una determinata operazione di fusione; dipende dai valori specifici degli input. I singoli passaggi dell'espansione senza fusione sono consentiti ogni 1 tolleranza ULP (o per qualsiasi istruzione che Direct3D richiama con una tolleranza più lenta rispetto a 1 ULP, maggiore è la tolleranza lenta consentita).
Le operazioni di fusione rispettano le stesse regole NaN delle operazioni senza fusione.
sqrt e rcp hanno 1 tolleranza ULP. Le istruzioni reciproche dello shader e di radice quadrata reciproca, rcp and rsq, hanno il proprio requisito di precisione separato e meno severo.
Moltiplicare e dividere ogni operazione a livello di precisione a virgola mobile a 32 bit (accuratezza a 0,5 ULP per la moltiplicazione, 1,0 ULP per il reciproco). Se x/y viene implementato direttamente, i risultati devono avere una precisione maggiore o uguale a quella di un metodo in due passaggi.
Regole a virgola mobile (a precisione doppia) a 64 bit.
I driver hardware e di visualizzazione supportano facoltativamente la virgola mobile a precisione doppia. Per indicare il supporto, quando viene richiamato ID3D11Device::CheckFeatureSupport con D3D11_FEATURE_DOUBLES, il driver imposta DoublePrecisionFloatShaderOps of D3D11_FEATURE_DATA_DOUBLES a VERO. Il driver e l'hardware devono quindi supportare tutte le istruzioni a virgola mobile e precisione doppia.
Le istruzioni a precisione doppia seguono i requisiti di comportamento IEEE 754R.
Il supporto per la generazione di valori denormalizzati è necessario per i dati a precisione doppia (nessun comportamento in modalità da scaricamento ad azzeramento). Analogamente, le istruzioni non leggono i dati denormalizzati come zero con segno, rispettano il valore denormalizzato.
Regole a virgola mobile a 16 bit
Direct3D supporta anche rappresentazioni a 16 bit di numeri a virgola mobile.
Formato:
- 1 bit di segno/i nella posizione del bit MSB
- 5 bit di esponente distorto (e)
- 10 bit di frazione (f), con un bit nascosto aggiuntivo
Un valore float16 (v) segue queste regole:
- se e == 31 e f != 0, v è NaN indipendentemente da s
- se e == 31 e f == 0, quindi v = (-1)s*infinity (infinito con segno)
- se e è compreso tra 0 e 31, v = (-1)s*2(e-15)*(1.f)
- se e == 0 e f != 0, quindi v = (-1)s*2(e-14)*(0,f) (numeri denormalizzati)
- se e == 0 e f == 0, quindi v = (-1)s*0 (con segno zero)
Le regole a virgola mobile a 32 bit contengono anche numeri a virgola mobile a 16 bit, regolati per il layout di bit descritto in precedenza. Le eccezioni includono:
- Precisione: Le operazioni senza fusione sui numeri a virgola mobile a 16 bit producono un risultato che è il valore rappresentabile più vicino a un risultato infinitamente preciso (arrotondamento al numero pari più vicino, secondo IEEE-754, applicato a valori a 16 bit). Le regole a virgola mobile a 32 bit rispettano 1 tolleranza ULP, le regole a virgola mobile a 16 bit rispettano 0,5 ULP per le operazioni senza fusione e 0,6 ULP per le operazioni con fusione.
- I numeri a virgola mobile a 16 bit mantengono i valori denormalizzati.
Regole a virgola mobile a 11 bit e a 10 bit
Direct3D supporta anche formati a virgola mobile a 11 bit e a 10 bit.
Formato:
- Nessun bit di segno
- 5 bit di esponente distorto (e)
- 6 bit di frazione (f) per un formato a 11 bit, 5 bit di frazione (f) per un formato a 10 bit, con un bit nascosto aggiuntivo in entrambi i casi.
Un valore float11/float10 (v) segue le regole seguenti:
- se e == 31 e f != 0, v è NaN
- se e == 31 e f != 0, v = +infinito
- se e è compreso tra 0 e 31, v = 2(e-15)*(1.f)
- se e == 0 e f != 0, quindi v = *2(e-14)*(0,f) (numeri denormalizzati)
- se e == 0 e f == 0, allora v = 0 (zero)
Le regole a virgola mobile a 32 bit contengono anche numeri a virgola mobile a 16 bit, regolati per il layout di bit descritto in precedenza. Le eccezioni includono:
- Precisione: le regole a virgola mobile a 32 bit rispettano 0,5 ULP.
- I numeri a virgola mobile a 10/11 bit mantengono i valori denormalizzati.
- Qualsiasi operazione che comporterebbe un numero minore di zero viene bloccata su zero.
Argomenti correlati