Zum 3DCenter Forum
Inhalt




Ein Blick auf die Effizienz-Features bei GeForce 3/4

20. März 2003 / von aths / Seite 3 von 5


   Wie die GeForce3 Bandbreite spart, Teil 2

 Lossless Z Compression

Z-Werte sind ein Maß für die "Tiefe" des Pixels, heutzutage meistens 24-bittige Ganzzahlwerte. Damit es keine Fehler bei der Bedeckungsprüfung gibt, muss in diesem Fall jede Komprimierung unbedingt verlustfrei erfolgen. Das zieht eine Reihe an Konsequenzen mit sich. Einerseits findet sich für jeden noch so guten Komprimierungsalgorithmus immer eine Bitfolge, die nicht komprimiert werden kann. Schwieriger wird es, wenn feste Komprimierungsraten garantiert werden sollen. Sollen Daten beispielweise um Faktor 2 komprimiert werden, zieht das unweigerlich nach sich, dass nur die Hälfte aller denkbaren Bitfolgen so stark komprimiert werden können.

Die GeForce3 bietet eine 4:1-Komprimierung. Das bedeutet zwangsläufig, dass 3/4 aller denkbaren Bitfolgen hiermit nicht komprimiert werden können. Zum Glück ist das Problem in der Praxis weniger schlimm, was am Entropie-Verhalten der Z-Werte liegt. Diese sind nämlich nicht chaotisch (hohe Entropie = viel Chaos, geringe Entropie = viel Ordnung).

Um das Verfahren praxistauglich zu machen, muss einmal mehr eine Entkoppelung von Pipeline und RAM durch einen Cache vorgenommen werden. Dieser Cache ist sinnvollerweise direkt im Chip integriert und beinhaltet in einer "Kachel" von beispielsweise 8x8 Pixeln alle Z-Daten. Da nebeneinander stehende Pixel gleichzeitig gerendert werden, könnte die Kachelgröße sinnvollerweise auch 8x4 betragen, nähere Informationen hierzu gibt nVidia leider nicht preis. Wird diese Kachel aus dem RAM angefordert, setzt der Dekomprimierungsalgorithmus an. Schlug die Komprimierung beim Schreiben fehl, steht die Kachel unkomprimiert im RAM und muss dementsprechend unkomprimiert über den Bus in den Chip.

Bevor die Komprimierung stattfindet, müssen die Z-Daten erst noch aufbereitet werden. Es ist logisch, dass Daten, die lange Bitfolgen aus lauter Nullen enthalten, gut komprimierbar sind. Da es sehr wahrscheinlich ist, dass sich Z-Werte von nahe zusammen stehenden Pixeln nur wenig unterscheidet, findet eine mehrfache Delta-Komprimierung statt. Weil das genaue Verfahren ein Betriebsgeheimnis von nVidia ist, können wir folgende Methode nur unter Vorbehalt gestellt anbieten:

  • 1. Ein Z-Wert aus der Kachel wird als Referenz genommen.
  • 2. Ansonsten wird nur die "Differenz der Differenz" zum Nachbar gespeichert.
  • 3. Die "Differenz zur Differenz" des nächsten Nachbars ist innerhalb eines Dreieckes gleich 0 oder zumindest sehr klein.
  • 4. Das ermöglicht eine sehr effektive Komprimierung.

Schlägt die Komprimierung fehl, wird das Bit, welches den Komprimierungsstatus anzeigt, auf 0 gesetzt und die Kachel "pur" übertragen. Ansonsten geht die komprimierte Kachel über den Bus. Da die Komprimierungrate auf 4:1 festgelegt ist, enfällt Overhead wie z.B. eine Größenangabe. Der Verkehr an Z-Daten über den Bus wird erheblich reduziert. Es bleibt mehr Bandbreite für andere Aktionen übrig.

Jedenfalls ist das meistens so. Es ließen sich auch Szenarien konstruieren, wo ständig neue Kacheln übertragen werden müssen, obwohl jeweils nur sehr wenige Werte daraus wirklich gebraucht werden. Dann ist dieser Weg sogar langsamer als die herkömmliche Methode. Da sich in der Praxis fast alle aufeinanderfolgende Polygone in räumlicher Nähe befinden, ist der Weg der Z-Buffer-Kachelung jedoch nützlich. Im übrigen beherrschte bereits der originale Radeon-Chip Z-Komprimierung.

Methode 3) Verlagerung von Datenströmen

Wir haben diese Methode an das Ende gestellt, um nicht zu weit vorgreifen zu müssen. Denn Caching ist nicht nur eine wichtige Methode, um den Datenfluss vom Speicherbus teilweise in den Chip zu verlagern, sondern wird auch mit den meisten anderen Verfahren zusammen eingesetzt. Nun ist es aber nicht damit getan, die Gatter für den onchip-Cache-Speicher bereitzustellen, denn der Cache muss auch verwaltet werden und es bedarf einer ausgeklügelten Logik, welche über den Verbleib der Daten im Cache entscheidet und das Laden aus dem lokalen RAM in den Cache sinnvoll regelt.

Dazu muss der Cache "wissen", welche Daten er vorrätig hält. Da das Schreiben über den Cache verzögert wird, muss z.B. dafür gesorgt werden, keine alten Daten aus dem RAM zu lesen, wenn der Schreibcache noch nicht in den RAM geschrieben wurde. Der Cache soll unter anderem Lastspitzen vermeiden und selbst möglichst wenig Last erzeugen, wobei Lastspitzen aber nicht immer vermeidbar sind. Deshalb sollte es eine "kluge" Logik geben.

Natürlich kann sie nicht wirklich intelligent sein, sondern nur bestimmten Schemen folgen. Diese "Verhaltensmuster" werden bei der Chipentwicklung simuliert und getestet, um mit möglichst wenig Cache möglichst viel zu erreichen. Um nahe ans Optimum zu kommen, sind stochastische Simulationen ein Weg, das heißt, ein Programm bildet die Cache-Strategie nach und misst dabei die Effizienz. Hierfür muss aber bekannt sein, in welchen zeitlichen Abständen Lese- bzw. Schreibanforderungen ankommen. Ein Cache lässt sich für eine gegebene Situation sehr gut optimieren, man versucht aber, lieber eine breite Palette an Szenarien abzudecken.

Über Cache-Verwaltung ließen sich ganze Bücher schreiben, wir wollen es hier nur kurz anreißen. Wenn ein Cache gefüllt wird, werden nicht nur die benötigten Daten gelesen, sondern auch noch die "in der Nähe". Denn es ist sehr wahrscheinlich, dass sie in Kürze ebenfalls gebraucht werden. Dafür ist dann aber eine Lastspitze in Kauf zu nehmen, der Speicherbus hat infolge dessen mehrere Takte zu tun, die Daten zu holen, während alle vier Pipelines in dieser Zeit warten müssen. Aus diesem Grunde ist es auch unsinnig, riesige Caches zu verwenden: Je größer der Speicher, desto mehr Daten fallen an, und desto länger ist der Bus belegt. Hier gilt es, einen guten Trade-off zu finden.

Cache wird bei allen 3D-Chips verwendet. Der Texturcache umfasst typischerweise einige Kilobyte, während die Puffer für einen Burst Write nur wenige Bytes fassen. Wie schon erwähnt, sprechen die Bausteine der Pipeline in der Regel nicht das Speicherinterface der Grafikkarte an, sondern arbeiten ausschließlich über ihren Cache. Ein kleiner Teil des aktuell bearbeiteten Z-Buffers ist bei der GeForce3 zum Beispiel ständig im Chip vorhanden, womit der Z-Verkehr größtenteils vom Speicherinterface in den Chip verlagert wird. Durch dieses Verfahren bleibt mehr Bandbreite für andere Pipeline-Bestandteile.






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

Shortcuts
nach oben