Gleitkommaregeln
Direct3D unterstützt mehrere Gleitkommadarstellungen. Alle Gleitkommaberechnungen werden unter einer definierten Teilmenge der IEEE 754 32-Bit-Gleitkommaregeln mit einfacher Genauigkeit ausgeführt.
32-Bit-Gleitkommaregeln
Es gibt zwei Regelsätze: diejenigen, die IEEE-754 entsprechen, und diejenigen, die vom Standard abweichen.
Berücksichtigte IEEE-754-Regeln
Einige dieser Regeln sind eine einzige Option, bei der IEEE-754 Auswahlmöglichkeiten bietet.
Dividiert durch 0 erzeugt +/- INF, mit Ausnahme von 0/0, was zu NaN führt.
Protokoll von (+/-) 0 erzeugt -INF.
Das Protokoll eines negativen Werts (außer -0) erzeugt NaN.
Die reziprozien Quadratwurzel (rsq) oder die Quadratwurzel (sqrt) einer negativen Zahl erzeugt NaN.
Die Ausnahme ist -0; sqrt(-0) erzeugt -0 und rsq(-0) erzeugt -INF.
INF - INF = NaN
(+/-) INF / (+/-)INF = NaN
(+/-) INF * 0 = NaN
NaN (any OP) any-value = NaN
Die Vergleiche EQ, GT, GE, LT und LE, wenn entweder oder beide Operanden "NaN" den Wert FALSE zurückgibt.
Vergleiche ignorieren das Vorzeichen 0 (sodass +0 gleich -0 ist).
Der Vergleich NE, wenn entweder oder beide Operanden NaN ist, WAHR zurückgibt.
Vergleiche eines Nicht-NaN-Werts mit +/- INF geben das richtige Ergebnis zurück.
Abweichungen oder zusätzliche Anforderungen von IEEE-754-Regeln
IEEE-754 erfordert Gleitkommavorgänge, um ein Ergebnis zu erzeugen, das den nächsten darstellbaren Wert für ein unendlich präzises Ergebnis darstellt, das als Round-to-Nearest-Even bezeichnet wird.
Direct3D 11 und höher definieren die gleiche Anforderung wie IEEE-754: 32-Bit-Gleitkommavorgänge erzeugen ein Ergebnis, das sich innerhalb von 0,5 Einheiten last-place (ULP) des unendlich genauen Ergebnisses befindet. Dies bedeutet, dass z. B. Hardware Ergebnisse auf 32-Bit abschneiden darf, anstatt round-to-nearest-even durchzuführen, da dies zu einem Fehler von höchstens 0,5 ULP führen würde. Diese Regel gilt nur für Addition, Subtraktion und Multiplikation.
Frühere Versionen von Direct3D definieren eine losere Anforderung als IEEE-754: 32-Bit-Gleitkommavorgänge erzeugen ein Ergebnis, das sich innerhalb einer Einheit letzten Stelle (1 ULP) des unendlich genauen Ergebnisses befindet. Dies bedeutet, dass z. B. Hardware Ergebnisse auf 32-Bit abschneiden darf, anstatt round-to-nearest-even durchzuführen, da dies zu Einem Fehler bei höchstens einem ULP führen würde.
Es gibt keine Unterstützung für Gleitkomma-Ausnahmen, Statusbits oder Traps.
Denorms werden bei Eingabe und Ausgabe eines mathematischen Gleitkommavorgangs auf sign-preserved zero geleert. Ausnahmen werden für alle E/A- oder Datenverschiebungsvorgänge vorgenommen, die die Daten nicht bearbeiten.
Zustände, die Gleitkommawerte enthalten, z. B. Viewport MinDepth/MaxDepth- oder BorderColor-Werte, können als Denormwerte bereitgestellt werden und vor der Hardwareverwendung möglicherweise nicht geleert werden.
Min- oder Max-Vorgänge leeren Denormalen für den Vergleich, aber das Ergebnis kann oder nicht entnormt werden.
NaN-Eingabe in einen Vorgang erzeugt immer NaN bei der Ausgabe. Das genaue Bitmuster des NaN ist jedoch nicht erforderlich, um gleich zu bleiben (es sei denn, der Vorgang ist eine unformatierte Verschiebungsanweisung , die keine Daten ändert.)
Min- oder Max-Vorgänge, für die nur ein Operand naN ist, geben den anderen Operanden als Ergebnis zurück (im Gegensatz zu Vergleichsregeln, die wir zuvor betrachtet haben). Dies ist eine IEEE 754R-Regel.
Die IEEE-754R-Spezifikation für Gleitkomma-Min- und Max-Vorgänge gibt an, dass das Ergebnis des Vorgangs der andere Parameter ist, wenn einer der Eingaben in min oder max ein ruhiger QNaN-Wert ist. Zum Beispiel:
min(x,QNaN) == min(QNaN,x) == x (same for max)
Eine Überarbeitung der IEEE-754R-Spezifikation hat ein anderes Verhalten für min und max übernommen, wenn eine Eingabe ein "signalierender" SNaN-Wert im Vergleich zu einem QNaN-Wert ist:
min(x,SNaN) == min(SNaN,x) == QNaN (same for max)
Im Allgemeinen folgt Direct3D den Standards für Arithmetik: IEEE-754 und IEEE-754R. Aber in diesem Fall haben wir eine Abweichung.
Die arithmetischen Regeln in Direct3D 10 und höher unterscheiden sich nicht zwischen stillen und signalierenden NaN-Werten (QNaN und SNaN). Alle NaN-Werte werden auf die gleiche Weise behandelt. Im Fall von Min und Max entspricht das Direct3D-Verhalten für jeden NaN-Wert der Behandlung von QNaN in der IEEE-754R-Definition. (Wenn beide Eingaben NaN sind, wird ein NaN-Wert zurückgegeben.)
Eine weitere IEEE 754R-Regel ist, dass min(-0,+0) == min(+0,-0) == -0 und max(-0,+0) == max(+0,-0) == +0, das das Zeichen berücksichtigt, im Gegensatz zu den Vergleichsregeln für signierte Null (wie zuvor gesehen). Direct3D empfiehlt hier das IEEE 754R-Verhalten, erzwingt es jedoch nicht; es ist zulässig, dass das Ergebnis des Vergleichs von Nullen von der Reihenfolge der Parameter abhängig ist, wobei ein Vergleich verwendet wird, der die Zeichen ignoriert.
x*1,0f ergibt immer x (mit Ausnahme von denorm geleert).
x/1.0f ergibt immer x (außer denorm flushed).
x +/- 0,0f führt immer zu x (außer denorm flushed). Aber -0 + 0 = +0.
Fused-Operationen (z. B. mad, dp3) erzeugen Ergebnisse, die nicht weniger genau sind als die am schlimmsten mögliche Serielle Anordnung der Auswertung der unfused Expansion des Vorgangs. Die Definition der schlimmsten möglichen Sortierung zum Zweck der Toleranz ist keine feste Definition für einen bestimmten Fused-Vorgang; sie hängt von den jeweiligen Werten der Eingaben ab. Die einzelnen Schritte in der unfused Erweiterung sind jeweils 1 ULP-Toleranz zulässig (oder für Anweisungen, die Direct3D mit einer laxen Toleranz als 1 ULP aufruft, ist die laxe Toleranz zulässig).
Fused-Vorgänge entsprechen den gleichen NaN-Regeln wie nicht fused-Vorgänge.
sqrt und rcp haben 1 ULP-Toleranz. Der Shader reziproke und reziproke Quadratwurzelanweisungen, rcp und rsq, haben eine eigene, getrennte, entspannte Genauigkeitsanforderung.
Multiplizieren und dividieren Sie jeden Vorgang auf 32-Bit-Gleitkommagenauigkeitsebene (Genauigkeit auf 0,5 ULP für multipliziert, 1,0 ULP für Kehrwert). Wenn x/y direkt implementiert wird, müssen die Ergebnisse größer oder gleich genau sein als eine zweistufige Methode.
64-Bit-Gleitkommaregeln (doppelte Genauigkeit)
Hardware- und Anzeigetreiber unterstützen optional Gleitkomma mit doppelter Genauigkeit. Wenn Sie id3D11Device::CheckFeatureSupport mit D3D11_FEATURE_DOUBLES aufrufen, legt der Treiber DoublePrecisionFloatShaderOps von D3D11_FEATURE_DATA_DOUBLES auf TRUE fest. Der Treiber und die Hardware müssen dann alle Gleitkommaanweisungen mit doppelter Genauigkeit unterstützen.
Anweisungen mit doppelter Genauigkeit folgen den IEEE 754R-Verhaltensanforderungen.
Unterstützung für die Erzeugung von denormalisierten Werten ist für Daten mit doppelter Genauigkeit erforderlich (kein Flush-to-Zero-Verhalten). Ebenso lesen Anweisungen keine denormalisierten Daten als signierte Null, sie berücksichtigen den Denorm-Wert.
16-Bit-Gleitkommaregeln
Direct3D unterstützt auch 16-Bit-Darstellungen von Gleitkommazahlen.
Format:
- 1 Zeichenbit (s)in der MSB-Bitposition
- 5 Bits von voreingenommenen Exponenten (e)
- 10 Bit Bruch (f) mit einem zusätzlichen ausgeblendeten Bit
Ein float16-Wert (v) folgt den folgenden Regeln:
- wenn e == 31 und f != 0, dann ist v NaN unabhängig von s
- wenn e == 31 und f == 0, dann v = (-1)s*unendlich (signiert unendlich)
- wenn e zwischen 0 und 31 liegt, dann v = (-1)s*2(e-15)*(1.f)
- wenn e == 0 und f != 0, dann v = (-1)s*2(e-14)*(0.f) (denormalisierte Zahlen)
- wenn e == 0 und f == 0, dann v = (-1)s*0 (signiert null)
32-Bit-Gleitkommaregeln enthalten auch 16-Bit-Gleitkommazahlen, die für das zuvor beschriebene Bitlayout angepasst wurden. Dabei gibt es folgende Ausnahmen:
- Genauigkeit: Unfused-Vorgänge auf 16-Bit-Gleitkommazahlen erzeugen ein Ergebnis, das den nächsten darstellbaren Wert für ein unendlich präzises Ergebnis darstellt (rundet auf das nächste sogar pro IEEE-754, angewendet auf 16-Bit-Werte). 32-Bit-Gleitkommaregeln entsprechen der 1 ULP-Toleranz, 16-Bit-Gleitkommaregeln entsprechen 0,5 ULP für unfused-Vorgänge und 0,6 ULP für fused-Vorgänge.
- 16-Bit-Gleitkommazahlen erhalten Denorms.
11-Bit- und 10-Bit-Gleitkommaregeln
Direct3D unterstützt auch 11-Bit- und 10-Bit-Gleitkommaformate.
Format:
- Kein Zeichenbit
- 5 Bits von voreingenommenen Exponenten (e)
- 6 Bits von Bruch (f) für ein 11-Bit-Format, 5 Bit bruch (f) für ein 10-Bit-Format mit einem zusätzlichen ausgeblendeten Bit in beiden Fällen.
Ein float11/float10-Wert (v) folgt den folgenden Regeln:
- wenn e == 31 und f != 0, dann ist v NaN
- wenn e == 31 und f == 0, dann v = +unendlich
- wenn e zwischen 0 und 31 liegt, dann v = 2(e-15)*(1.f)
- wenn e == 0 und f != 0, dann v = *2(e-14)*(0.f) (denormalisierte Zahlen)
- wenn e == 0 und f == 0, dann v = 0 (null)
32-Bit-Gleitkommaregeln enthalten auch 11-Bit- und 10-Bit-Gleitkommazahlen, die für das zuvor beschriebene Bitlayout angepasst wurden. Es gelten folgende Ausnahmen:
- Genauigkeit: 32-Bit-Gleitkommaregeln entsprechen 0,5 ULP.
- 10/11-Bit-Gleitkommazahlen erhalten Denorms.
- Jeder Vorgang, der zu einer Zahl kleiner als 0 führen würde, wird auf Null geklemmt.
Verwandte Themen