Share via


Regole a virgola mobile (Direct3D 11)

Direct3D 11 supporta diverse rappresentazioni a virgola mobile. Tutti i calcoli a virgola mobile operano in un subset definito delle regole a virgola mobile IEEE 754 a 32 bit.

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.

  • Divide per 0 produce +/- INF, ad eccezione di 0/0 che genera NaN.
  • il log di (+/-) produce -INF. il log di un valore negativo (diverso da -0) produce NaN.
  • La radice quadrata reciproca (rsq) o la 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 (any OP) any-value = NaN
  • I confronti EQ, GT, GE, LT e LE, quando entrambi gli operandi sono NaN restituisce FALSE.
  • I confronti ignorano il segno 0 (quindi +0 uguale a -0).
  • Il confronto NE, quando o entrambi gli operandi è NaN restituisce TRUE.
  • 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 round-to-near-even. Direct3D 11 definisce lo stesso requisito: le operazioni a virgola mobile a 32 bit producono un risultato compreso tra 0,5 unit-last-place (ULP) del risultato infinito preciso. Ciò significa che, ad esempio, l'hardware può troncare i risultati a 32 bit anziché eseguire round-to-near-even, in quanto ciò comporta l'errore di almeno 0,5 ULP. Questa regola si applica solo all'aggiunta, alla sottrazione e alla moltiplicazione.

  • Non è disponibile alcun supporto per eccezioni a virgola mobile, bit di stato o trap.

  • I denorm vengono scaricati per firmare zero in base all'input e all'output di qualsiasi operazione matematica a virgola mobile. Le eccezioni vengono effettuate per qualsiasi operazione di I/O o di spostamento dei dati che non modifica i dati.

  • Gli stati che contengono valori a virgola mobile, ad esempio Viewport MinDepth/MaxDepth, i valori BorderColor possono essere forniti come valori denorm e potrebbero non essere scaricati prima che l'hardware li usi.

  • Min o max operations flush denorms for confronto, ma il risultato può o meno essere denorm flushed.

  • L'input NaN a un'operazione produce sempre NaN sull'output. Ma il modello di bit esatto del NaN non è necessario rimanere invariato (a meno che l'operazione non sia un'istruzione di spostamento non elaborata, che non modifica i dati).

  • Operazioni min o max per cui un solo operando è NaN restituisce 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 a virgola mobile min e max indica che se uno degli input a min o max è un valore QNaN tranquillo, 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 "signaling" rispetto a un valore QNaN:

    min(x,SNaN) == min(SNaN,x) == QNaN (same for max)
    
    

    In genere, Direct3D segue gli standard per aritmetica: IEEE-754 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 (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 la 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, che rispetta il segno, in contrasto con le regole di confronto per lo zero firmato (come abbiamo visto in precedenza). Direct3D consiglia il comportamento IEEE 754R qui, ma non lo applica; è consentito che il risultato del confronto di zero dipende dall'ordine dei parametri, usando un confronto che ignora i segni.

  • x*1.0f genera sempre x (ad eccezione del denorm scaricato).

  • x/1.0f genera sempre x (ad eccezione del denorm scaricato).

  • x +/- 0.0f genera sempre x (ad eccezione del denorm scaricato). Ma -0 + 0 = +0.

  • Le operazioni fuse (ad esempio mad, dp3) producono risultati che non sono meno accurati del peggiore possibile ordinamento seriale della valutazione dell'espansione nonfusa dell'operazione. La definizione del peggiore possibile ordinamento, allo scopo della tolleranza, non è una definizione fissa per un'operazione fusibile specificata; dipende dai valori specifici degli input. I singoli passaggi nell'espansione senzafusi sono consentiti ogni tolleranza ULP 1 (o per qualsiasi istruzione Direct3D chiama con una tolleranza più lax rispetto a 1 ULP, la tolleranza più lax è consentita).

  • Le operazioni fuse rispettano le stesse regole NaN delle operazioni non fuse.

  • sqrt e rcp hanno 1 tolleranza ULP. Le istruzioni reciproca e reciproca della radice quadrata, rcp e rsq, hanno un proprio requisito di precisione rilassato separato.

  • Moltiplicare e dividere ogni operazione a livello di precisione a virgola mobile a 32 bit (accuratezza a 0,5 ULP per moltiplicare, 1,0 ULP per reciproca). Se x/y viene implementato direttamente, i risultati devono essere di precisione maggiore o uguale a quello di un metodo in due passaggi.

Regole a virgola mobile a 64 bit (precisione doppia)

I driver hardware e display supportano facoltativamente virgola mobile a precisione doppia. Per indicare il supporto, quando si chiama ID3D11Device::CheckFeatureSupport con D3D11_FEATURE_DOUBLES, il driver imposta DoublePrecisionFloatShaderOps di D3D11_FEATURE_DATA_DOUBLES su TRUE. Il driver e l'hardware devono quindi supportare tutte le istruzioni a virgola mobile a precisione doppia.

Le istruzioni di precisione doppia seguono i requisiti di comportamento IEEE 754R.

Il supporto per la generazione di valori denormalizzati è necessario per i dati con precisione doppia (nessun comportamento di scaricamento a zero). Analogamente, le istruzioni non leggeno i dati denormalizzati come zero firmato, rispettano il valore denorm.

Regole a virgola mobile a 16 bit

Direct3D 11 supporta anche rappresentazioni a 16 bit di numeri a virgola mobile.

Formato:

  • 1 bit di segno (s)nella posizione del bit MSB
  • 5 bit di esponente con pregiudizi (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 firmato)
  • se e è compreso tra 0 e 31, v = (-1)s*2(e-15)*(1.f)
  • if 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 (zero firmato)

Le regole a virgola mobile a 32 bit contengono anche numeri a virgola mobile a 16 bit, regolati per il layout a bit descritto in precedenza. Alcune eccezioni:

  • Precisione: operazioni senzafusi sui numeri a virgola mobile a 16 bit producono un risultato che rappresenta il valore rappresentabile più vicino a un risultato infinitamente preciso (arrotondato fino al più vicino, per IEEE-754, applicato ai valori a 16 bit). Le regole a virgola mobile a 32 bit sono conformi a 1 tolleranza ULP, le regole a virgola mobile a 16 bit rispettano 0,5 ULP per operazioni nonfuse e 0,6 ULP per le operazioni fuse.
  • I numeri a virgola mobile a 16 bit mantengono i denorm.

Regole a virgola mobile a 11 bit e a 10 bit

Direct3D 11 supporta anche formati a virgola mobile a 11 bit e a 10 bit.

Formato:

  • Nessun segno
  • 5 bit di esponente con pregiudizi (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, quindi 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)
  • if e == 0 e f == 0, quindi v = 0 (zero)

Le regole a virgola mobile a 32 bit contengono anche numeri a virgola mobile a 11 bit e a 10 bit, regolati per il layout a bit descritto in precedenza. Le eccezioni sono le seguenti:

  • Precisione: le regole a virgola mobile a 32 bit sono conformi a 0,5 ULP.
  • I numeri a virgola mobile a 10/11 bit mantengono i denorm.
  • Qualsiasi operazione che comporta un numero minore di zero viene bloccata su zero.

Risorse

Trame