Zum 3DCenter Forum
Inhalt




Das Floating-Point-Format im Detail

Teil 1 von 3 / 1. März 2004 / von aths / Seite 3 von 13


   FX12 - Ein echtes Festkomma-Format

Nur neun Bits beim FX9-Format sind ziemlich wenig: Ein Bit geht für's Vorzeichen weg, es bleiben acht Bit Auflösung für den Bereich 0 bis 1. Da ist ein Vorkomma-Anteil nicht mehr mit drin. Die GeForceFX rechnet im Register Combiner jedoch immerhin mit FX12. Um negative Werte zu speichern, wird die Zweierkomplement-Darstellung genutzt. FX12 ist dank den zusätzlichen Bits genauer als FX9, jedoch zu einem Preis: Textur-Farben können nicht mehr direkt übernommen werden. Bekanntlich entspricht 1,0 im FX8-Format 1111'1111, was sehr einfach in FX9 umgewandelt werden kann: 0'1111'1111.

Wird FX9 einfach um drei Bits erweitert, einmal vor dem Komma, zweimal "ganz hinten", hätte man für 1,0 zunächst 00,11'1111'1100. Die FX12-Darstellung ist aber anders definiert: 1,0 entspricht 01,00'0000'0000. FX12 hat eine echte Vorkomma-Stelle, anders als FX8 oder FX9. Die GeForceFX-Chips verfügen über Einheiten, um Textur-Farben, die ja zumeist als FX8 vorliegen, in FX12 zu überführen. Eine spezielle Konvertierung ist natürlich auch für FP16 bzw. FP32 notwendig. Ebenso muss das berechnete Ergebnis zurückgewandelt werden. Diese zusätzlichen Berechnungen verlängern die Pixel-Pipeline, doch es lohnt sich: FX12 löst den Nachkomma-Bereich immerhin vier mal feiner auf als FX9, außerdem steht ein Wertebereich von -2,0 bis +1,9995 zur Verfügung (statt nur von -1,003 bis 1,0.)

Wie rechnet man Dezimalkomma-Stellen in die binäre Darstellung um? Dazu gibt es einen "Trick", womit man bequem nacheinander an so viele Kommastellen kommt, wie man benötigt. Angenommen, von 0,213 sollen 10 binäre Nachkomma-Stellen ausgerechnet werden. Wir tippen 0,213 in den Taschenrechner und legen los:


Umrechnung von Kommastellen in das Binärformat

Zunächst wird die Zahl 0,213 verdoppelt. Wir erhalten 0,426. Da wir nach wie vor eine Null vor dem Komma haben, schreiben wir diese Null raus. Das neue Ergebnis wird wieder verdoppelt, wir erhalten 0,852. Es bleibt bei einer Null vor dem Komma, die wir wieder raus schreiben. Die nächste Verdopplung führt zu 1,704. Die Eins vor dem Komma schreiben wir raus, und rechnen nur mit dem Nachkomma-Teil weiter, also mit 0,704. So wird fortgefahren, bis 11 Stellen ermittelt wurden. Die 11. Stelle ist eine 0, das heißt, dass wir die 10. Stelle nicht aufrunden müssen. 0,213 entspricht binär also 0,0011011010 (einfach die Komma-Stellen aus der Tabelle von oben nach unten abgelesen). Im FX12-Format hat man die Bitfolge 00,00'1101'1010.


   Es geht um's Geld - Fixpoints auf der CPU

Eine andere Festkomma-Darstellung ist der Datentyp "Currency". Eigentlich handelt es sich um einen Integer-Wert, der jedoch in Schritten von einem Zehntausendstel speichert. Finanzmathematische Berechnungen werden ja meist nicht mit nur zwei Kommastellen (also herunter bis zum Cent) sondern auf das hunderstel Cent genau ausgeführt. Das entspricht einem zehntausenstel Euro. Die Berechnungsfehler bleiben somit klein genug, dass sich das gerundete Rechenergebnis vom gerundeten "wahren" Ergebnis (mit unendlicher Genauigkeit berechnet) nicht unterscheiden sollte.

Da "1 Euro" als "10000 Zehntausendstel Euro" gespeichert wird, gilt das gleiche wie für jede Normierung auf anderen Wertebereich: ADD und SUB funktionieren wie gewohnt, beim MUL muss das Ergebnis nach der Berechnung re-normiert werden, und zwar in diesem Falle noch mal mit 1/10000 multipliziert. Der Currency-Datentyp ist der CPU als solcher nicht bekannt, die Re-Normierung übernimmt die Software. Diese zusätzlichen Rechnungen gehen natürlich zu Lasten der Performance, dafür wird die gängige Finanz-Mathematik exakt simuliert.

Weil gleich korrekt zurück normiert wird, ist eine weitere Korrektur nicht mehr notwendig. Um FX8 nach dem MUL korrekt zu normieren, müsste man mit 1 / 255 multiplizieren, anstatt um 8 Bits zu shiften, was * 1 / 256 entspricht. Dieser Fehler wird dort mit der Bit-Korrektur am Ende berichtigt. Currency wird aber wie gesagt vornherein korrekt zurück normiert.

Alle interessanten Fixpoint-Typen haben wir jetzt besprochen. Wir sahen, dass die Rechnungen mit Fixpoint einige Fallen bereit halten. Man mag fragen, wozu ein neues Format erfinden? Wenn die Genauigkeit nicht ausreicht, könnte man doch einige zusätzliche Nachkomma-Bits anfügen und die Probleme damit in den Griff bekommen - oder?


   Eine Frage der Quantisierung

Alle bisher vorgestellte Formate haben eines gemeinsam: Die darstellbaren Werte sind gleichmäßig abgestuft. Das erscheint naheliegend und "natürlich". Außerdem lässt sich damit schön einfach rechnen. Welche Auswirkungen hat das noch? Betrachten wir ein Beispiel mit FX8, und zwar das Bitmuster 1100'0000. Es steht für 192 / 255 = 0,753. Doch halt: Ist wirklich genau 0,753 gemeint? Das kann man ja nicht so genau wissen! Wir befinden uns in der Digital-Technik. Bevor ein Wert digital abgebildet werden kann, muss er auf die nächstliegende Quantisierungsstufe gerundet werden. Das heißt, 0,752 oder 0,754 würden als FX8 ebenfalls mit 1100'0000 dargestellt. Unser Bitmuster steht also nur für "ungefähr 0,753". Ungenauigkeiten sind bei einer Quantisierung unvermeidlich.

Das Quantum ist die kleinste Einheit. Der Begriff "Quantensprung" wird demzufolge ständig falsch verwendet, denn wörtlich heißt das, der kleinstmögliche Sprung. Physikalisch ist hiermit eine Zustandsänderung gemeint, welche nur in ganzen Quanten erfolgen kann. Es gibt in der Welt zahllose Beispiele für Quanten, zum Beispiel die Ladungs eines Elektrons. Jedes Elektron hat die Ladung von 1 e0 (Elementarladung). Es ist nicht möglich, irgendeine elektrische Ladung zu erzeugen, die sich nicht als ganzzahliger Faktor von e0 darstellen lässt. Jede elektrische Ladung ist demzufolge gequantelt. Soviel als kleiner Abstecher, um zu zeigen, dass es Quantisierung nicht erst seit der Rechentechnik gibt.

Nun sind die Quanten in der Natur dermaßen klein, dass wir ohne spezielle Meßgeräte die Unterschiede zwischen einzelnen Quanten nicht feststellen können. Anders in der Computerwelt: Bei unserem 8-Bit-Beispiel gibt es nur 256 Quantisierungsstufen. Bei FX8 ist jede Stufe 1/255 "breit", das entspricht etwa 0,004 von Stufe zu Stufe. Mit anderen Worten gibt es um jeden Wert herum (also nach oben, und nach unten) eine Unsicherheit von jeweils 0,002. Bei FX8 wird alles von 0,751 bis 0,755 mit dem gleichen Bitmuster kodiert. Das heißt, man hat einen Unsicherheitsfaktor von 0,004 auf 0,753, das sind gut 0,5%.

0,5% Unsicherheit? Damit kann man vermutlich durchaus leben. Doch betrachten wir die andere Seite der Medaillie: Das Bitmuster 0000'0011 steht für 3 / 255 = 0,012. Der Unsicherheits-Bereich von 0,004 muss jetzt auf 0,012 bezogen werden, das heißt wir haben hier einen Unsicherheitsfaktor von 33%! Im Klartext: Je kleiner die Werte werden, desto schlimmer schlägt der Quantisierungsfehler zu.

Nun mag man einwenden, 0,012 ist als Helligkeit gesehen bereits so dunkel, da stört die große Unsicherheit auch nicht mehr. Doch man sollte sich vor Augen führen, dass dieser Wert auch das Zwischenergebnis einer Rechnung sein kann. Das Endergebnis wird natürlich keinesfalls mehr genauer, sondern kann auf jeder Seite um bis zu 16% daneben liegen, zusätzliche Fehler durch weitere Berechnungen noch gar nicht berücksichtigt.


Ist es dunkel genug, fallen auch 50% Helligkeits-Abweichung nicht auf. Bei entsprechender Helligkeit sind 20% Unterschied sofort sichtbar.

Rechnet man mit dunklen Helligkeits-Werten weiter, wird das Endergebnis besonders stark verfälscht. Das ist mit ein Grund dafür, dass Light-Maps in Wahrheit Shade-Maps sind: Light-Maps sind Texturen, die multiplikativ mit der Base Map verrechnet werden. Texturen können keine Intensitäten größer 1 speichern, höchstens kleinere; das heißt, Light-Maps dunkeln nur ab. Die eigentlichen Base-Texturen sind für volle Beleuchtung gedacht, und werden in Kombination mit den Light Maps dort abgedunkelt, wo das Licht nicht so stark hinfällt. Das Ausgangs-Material kann somit den vollen Dynamik-Umfang von FX8 nutzen.

Man könnte sich ausmalen, wie es aussieht, wenn man alle FX8-Zahlen in ein Diagramm einzeichnet. Das ergibt eine Funktion, durch die man eine Linie ziehen könnte. Deshalb wird auch von linearer Quantisierung gesprochen. Wir haben das einmal für FX5-Zahlen gemacht:

Klicken für großes Bild
Blau: Die Zahlen-Werte, grün: die Abstände zwischen den Zahlenwerten. Rot: Der relative Fehler. Bei kleinen Zahlen ist der relative Fehler überproportional groß (Klicken für großes Bild).






Kommentare, Meinungen, Kritiken können ins Forum geschrieben werden - Registrierung ist nicht notwendig Zurück / Back Weiter / Next

Shortcuts
nach oben