Pixelshader: Reicht "Partial Precision" aus?
29. November 2004 / von aths / Seite 2 von 2
FP16: Ist _PP minderwertig?
Bei der Entwicklung des NV40-Chips waren die DirectX9-Spezifikationen bekannt, und Nvidia baute dann auch keine extra Units für FX12 mehr ein. Eine Ausnahme sind Konvertierungs-Einheiten: Mit dem FX12-Format kann man somit scheinbar noch arbeiten, aber intern wird das als FP16 gehandhabt. Obwohl als für FP32 optimiertes Design vermarktet, gewinnt der NV40-Chip aus der Nutzung von FP16 oft mehr Leistung als der NV35-Chip, welcher wiederum von FP16 mehr profitiert als NV30-Chip. Als ganz grobe Richtwerte kann man hierbei annehmen: NV30 gewinnt 10%, NV35 20% und NV40 30%. Der tatsächliche Gewinn hängt aber sehr von den konkreten Umständen ab. Bei bestimmten Shadern gewinnt NV40 mit _PP auch mal weniger als NV35. Natürlich ist die NV40-Grundleistung in jedem Falle höher als beim Vorgänger.
Die Frage steht: Ist _PP schlecht, nur weil man gegenüber "Full Precision" eben weniger Auflösung hat? Aus unserer Sicht sollte sich ATI mit den Vorwürfen zurückhalten, wenn für NV-Hardware bestimmte Shaderteile in FP16 gerechnet werden, denn beim Shader Mdel 3.0 gilt ihr FP24-Format ebenfalls nur als "Partial Precision". Andererseits darf der Leistungsgewinn mit FP16 nicht dazu führen, dass die GeForce-Karten schlechtere Bildqualität abliefert. Crytek bot mit dem Farcry 1.1 Patch ein gutes Beispiel, wie man schlechte Bildqualität erzeugt - interessanterweise ist daran jedoch nicht _PP schuld.
Denn das R300-Shaderset, auf _PP gezwungen, liefert anständige Bildqualität bei erträglicher Performance. Die Texturoperationen werden trotz _PP-Flag übrigens immer mit FP32 ausgeführt, der Treiber ignoriert das _PP dort einfach. Für "einfache" Shader ist FP16 also fast immer ausreichend, FP24 bietet entsprechend noch Reserven. Da wir nun wissen, dass FP16 meist noch gute Ergebnisse liefert, lässt sich begründet annehmen, dass FX12 für viele Pixelshader-Teile ebenfalls noch ausreichen würde.
Pikant ist die Lage – nach unserem Kenntnisstand – beim Actionkracher Half-Life 2. Weil man innerhalb eines 2.0er Pixelshaders kein FX12 einsetzen darf, gab es zunächst für die GeForceFX ein "gemischtes" Shaderset: Einfache Effekte werden mit DirectX8-Shadern gerendert, aufwändige Effekte mit DirectX9-Shadern. Selbstverständlich wurde, wo es sinnvoll war, in DirectX9-Pixelshadern das _PP-Flag gesetzt.
Allerdings ist dieser Mischmodus inzwischen wieder entfernt worden, die GeForceFX wird jetzt als DirectX8-Karte angesehen. Die GeForce6-Serie geht als DirectX9-Karte durch, allerdings, soweit wir wissen, wurden aus den Shadern die _PP-Flags entfernt. Damit wird die NV40-Architektur natürlich gebremst. Wir kennen allerdings keine Benchmarks, welche zeigen würden, dass der NV40 in Half-Life 2 durch _PP spürbar Leistung gewinnen würde. Den größten Flaschenhals vermuten wir deshalb bei der Texturfüllrate.
Wir nehmen an, dass Nvidia per Treiber "optimieren" wird, was noch drin ist. Da wird natürlich automatisch der Vorwurf einer unerlaubten "Optimierung" aka Cheat laut, wenn hierbei eine geringere Präzision genommen wird als der Shader nominell anfordert. Andererseits interessiert das Endergebnis, und sofern der Treiber wirklich zuverlässig nur die unkritischen Shaderteile um _PP ergänzt, wirkt sich das auf die Bildqualität nicht negativ aus. Allerdings darf ein WHQL-Treiber nicht eigenmächtig _PP verwenden. Handoptimierte Shader im Treiber zu hinterlegen lehnen wir ja grundsätzlich ab, hier sollte man die Zeit lieber den allgemein anwendbaren Optimierungs-Algorithmen zugute kommen lassen.
Jeder Grafiktreiber sollte standardmäßig genau das tun, was ihm aufgetragen wird. Akzeptabel wäre ein Schalter, mit welchem der Anwender entscheiden kann, ob der Treiber Shader daraufhin prüft, FP16 verwenden zu können. Die einfachste Lösung bietet natürlich ATI, die im Shader Model 2.0 gar kein _PP unterstützen und alles gleich mit voller Präzision berechnen, und das ohne Leistungsschwächen zu zeigen.
Unsaubere Methoden
Die Gesamtperformance setzt sich aus vielen unterschiedlichen Aspekten zusammen. Will man die Auswirkungen von Partial Precision diskutieren, sind auch die Begleitumstände zu berücksichtigen, die bei "Optimierungen" auftreten. Deshalb geht es in diesem Kapitel weniger um die arithmetische Rechengenauigkeit.
Ein weißes Hemd hat hierbei keiner. Im Krieg um Marktanteil und Profit ist es ATI und Nvidia gleichgültig, ob sie sinnvoll handeln oder nicht. Beispielsweise wurde von Nvidia nicht etwa erklärt, warum die GeForceFX im 3DMark03 wirklich so zurückliegt. Man beschuldigte Futuremark, nicht repräsentative Situationen genommen zu haben (diese Argumentation ist in Teilen richtig) – und ercheatete sich dann mit ziemlich dreisten Methoden einen höheren Score, wozu weitaus mehr zählt, als ungefragt FP16 zu verwenden.
Lustigerweise lag die GeForceFX gegenüber den Radeon-Karten in DirectX9-Spielen dann aber tatsächlich um etwa den gleichen Faktor zurück, wie der unverfälschte 3DM-Score andeutet. Trotz fragwürdiger Bench-Methoden sowie dem äußerst sparsamen Einsatz von DirectX9-Shadern gab der 03er Benchmark somit trotzdem letztendlich in etwa die Leistungsrelation in DirectX9-Spielen wieder.
Natürlich fragt man als 3D-Interessierter, warum dies so ist wie es ist. Mit Cheating verspielt sich ein IHV aber jedes Vertrauen. Nur weil man bei Nvidia der Meinung gewesen sein mag, dass man die bessere Grafikkarte entwickelt hätte, das aber leider in den oft genutzten Benchmarks nicht ersichtlich ist, darf man sich noch lange nicht den gewünschten Punktestand erschwindeln. Demzufolge können wir keinen Vertrauensvorschuss geben, dass nicht auch mittels _PP ungefragt "optimiert" werden könnte.
Nvidia nutzt jetzt undurchsichtige Treiber-"Optimierungen" für Doom 3. Einerseits zur Freude der Besitzer einer GeForceFX oder GeForce6. Andererseits zum Ärger all jener, die gerne die tatsächliche Hardware-Leistung sehen möchten. ATI ist im Bereich des Shaderreplacments auch nicht unbefleckt, in einem 3DMark03-Einzeltest erschwindelten sie sich mal knapp 10% Leistung. Mathematische Äquivalenz des Shaders ist dabei kein akzeptabler Grund: Handoptimierung für Benchmarks verzerren das Ergebnis in jedem Fall, da Leistung vorgespiegelt wird, die in Spielen objektiv nicht nutzbar ist.
Bei Doom 3 zog ATI mit dem Shaderreplacement nach. Auch der Texturfilter wird immer weiter "optimiert" (sprich, zugunsten der Leistung verschlechtert), und zwar von beiden großen IHVs. Besitzer einer GeForce6 beklagen sichtbares Texturflimmern im Zusammenhang mit anisotroper Filterung. Wie sinnvoll, dass Besitzer einer ach so modernen Shader Model 3.0 Karte mit Flimmer-Texturen abgespeist werden ;-).
Leider ist das mit den IHVs immer eine höchst unergiebige Diskussion: Sie argumentieren, die Bildqualität sei vielleicht anders, aber nicht schlechter. Das hörten wir schon – von allen Beteiligten – als es um die reduziert trilineare Texturfilterung ging. Das Tor ist längst aufgestoßen, der Begriff "Bildqualität" wird von den IHVs umdefiniert, wie es gerade passt. So vermarktet ATI die alten R300-Techniken im R420 jetzt neu als "High Definition", obwohl die tatsächliche Texturqualität gegenüber der Radeon 9700 standardmäßig abgesenkt wurde.
Valves seltsame Politik beim Shaderset für Half-Life 2 lässt dem Gedanken Spielraum, dass es besondere Entwicklungshilfe von ATI gab, denn die GeForceFX-Serie wird durch das von Half-Life 2 gewählte DirectX8-Shaderset abgewertet. Dass die Radeon-Karten in Half-Life 2 besonders gut performt und den NV40 überbietet, liegt nicht an womöglich besserer Pixelshadertechnik, sondern am Flaschenhals von Half-Life 2: Texturfüllrate. Aufgrund der höheren Taktrate berechnet der R420-Chip die Pixel schlicht flinker als der NV40-Chip. Doch immerhin: Aufgrund dieses Umstandes hat der NV40-Chip durch die fehlende _PP-Flags auch keine großen Nachteile. Der NV40 wurde für die Ausführung langer Shader gebaut und kann bei kurzen Pixelshader-Programmen bestimmte Architektur-Vorteile nicht ausspielen. Allerdings ist man bei kurzen Pixelshadern so oder so tendenziell texturfüllratenlimitiert.
Die bei den aktuellen Radeon X800 Grafikkarten höhere Texturfüllrate alleine erklärt ATIs teilweise wirklich großen Vorsprung noch nicht ganz. Vielleicht erwarten uns ja noch Entdeckungen à la Doom 3, wo sich herausstellte, dass Nvidia schon vor dem Release des Spieles hoch "optimierte" Treiber herausbrachte.
Für Spiele, die absehbar Zugpferde darstellen, scheuen die IHVs offenbar keine Mühe. Angesichts endlicher Ressourcen bleiben da kleinere Titel auf der Strecke. Half-Life 2 bietet zwar hervorragende Grafik, erreicht dies aber mit herkömmlichen Methoden – weshalb die Performance auch auf älteren Karten noch so gut ist. Half-Life 2 eignet sich jedenfalls nicht, um die Anforderungen zukünftiger Engines abzuschätzen.
Zwei Seiten der Medallie
Jeder IHV will als derjenige gelten, der die beste (landläufig: schnellste) Hardware anbietet. Da "optimiert" und cheatet man (die Grenzen sind fließend), verdreht Tatsachen und verschweigt wichtige Fakten. "Technical Briefs" bzw. "White Papers", egal aus welchem Hause, verwirren trotz scheinbar technischem Inhalt oft mehr als dass sie aufklären. Nvidia lobte sich im Zuge des Shader Models 3.0 erneut mit dem FP32-Support und suggeriert damit generell bessere Bildqualität. Da (sinnvollerweise) einiges durchaus mit FP16 berechnet worden sein kann, ist offen, ob das Endergebnis wirklich besser ist als durchgängig in FP24 gerechnet.
"Optimerungspotenzial" beim AF, von ATI "entdeckt", wird jetzt auch von Nvidia nachgeahmt. All das geht zulasten der Bildqualität – es ist ein Kampf auf dem Rücken des Kunden. Texturfilterung hat dabei auch etwas mit Präzision zu tun: Je schlechter die Filterung, desto unpräzisier sind die Input-Daten für den Pixelshader.
Wenn man so argumentiert, warum verlangt man nicht im gleichem Zuge durchgehende Full Precision für arithmetische Rechnungen im Pixelshader? Weil _PP grundsätzlich sinnvoll ist, wenn das Endergebnis (nicht pro Renderpass, sondern pro sichtbarem Pixel) in jeder Farbkomponente um maximal 1 Bit vom "wahren" Wert abweicht. ATIs Alphablending-Einheiten z. B. haben einen eingebauten Rundungsfehler, der tendenziell zu dunkle Farben liefern. Kein Problem, solange jedes Pixel maximal einmal geblendet wird. Liegen mehrere Schichten übereinander, kann sich der Rechenfehler jedoch in den wahrnehmbaren Bereich hinein aufschaukeln.
Partial Precision darf natürlich nur dort verwendet werden, wo man höhere Präzision wirklich nicht braucht. Dagegen sorgt die angesprochene Spirale der "Optimierungen" am Texturfilter für Abweichungen, die oft wesentlich größer als 1 Bit sind. Außerdem bekommt man einerseits nur unscharfe, in anderen Bereichen flimmrige Texturen. In einer Zeit, wo man unbedingt in 1600x1200 benchen muss, und dabei in der Regel die Lochmaske des Monitors überfährt, fällt das im Benchmark natürlich nicht so sehr auf. Was Spiele angeht, wurden wir in kleinen Schritten an immer schlechtere Texturqualität gewöhnt. Was man im Control Panel an- und abschalten kann, wird leider nur unzureichend von den IHVs dokumentiert.
Wir würden uns eine vergleichbare Optimierung, natürlich offen und ehrlich dokumentiert, auch für den PP-Einsatz wünschen. Immerhin kann der Technikfreak mit dem Tool 3D-Analyze etwas herumexperimentieren.
Partial Precision: Ein Werkzeug
"The right tool for the right job": Wofür bilineare Filterung ausreicht, sollte man sie auch nehmen. Hier ist aber der Entwickler gefragt, AF für die Texturen selbst zu setzen. Ansonsten erzwingt der Anwender AF per Treiber, womit auch einfache Lookups anisotrop gefiltert werden – was schlecht für die Leistung ist. Analog sollte man wo FP16 ausreicht, auch FP16 nehmen. Doom 3 setzt sowohl den AF-Grad als auch das PP-Flag von sich aus. Dabei ist das Flag fest im Shader vermerkt. Wenn ein mögliches automatisches Optimierungs-Tool ein oder zwei Möglichkeiten _PP zu setzen übersehen würde, wäre das ja kein Beinbruch. Hauptsache es wird keine Bildqualität geopfert.
Richtig ist ATIs Argument, dass der Umgang mit mehr Datenformate immer auch einen Mehraufwand bedeutet. Insofern könnte man das Verbot, beim Shader Model 2.0 oder beim GL_ARB_fragment_program noch FX12 zu nutzen, als Bemühung um Einheitlichkeit werten. Allerdings ist ein _PP möglich (und muss mindestens FP16-Genauigkeit bieten), was ja genau dem Gedanken Rechnung trägt, zu Lasten der Genauigkeit Performancegewinne zu erzielen, da viele Berechnungen keine besonders hohe Genauigkeit brauchen.
Deshalb ist es unverständlich, dass FX12 gar nicht mehr erlaubt ist, wo dieses Format ebenfalls oft reichen würde. GeForce 1/2/3/4 rechnen gar nur mit FX9, und trotzdem sieht damit nicht nur Max Payne, sondern auch Doom 3 noch durchaus ansprechend aus. Natürlich benötigen neue Engines, die richtig auf Shader setzen, bessere Formate. So verlockend das Gebot der Einheitlichkeit ist: Ein Format für alles überfordert die heutigen technischen Möglichkeiten. ATI bietet nur FP24, was bei bestimmten Rendertechniken in der Forschung und Entwicklung bzw. in der Content Creation grenzwertig ist (um nicht zu sagen, ungeeignet), aber für Spiele noch länger ausreichen wird. Nvidia setzt auf ein Mischsystem von FP32 und FP16, die GeForceFX-Karten bieten zusätzlich noch FX12.
Für bestimmte Rechnungen, nämlich Fog-Blending und vor allem Normalisierung, vermutlich auch für das Wurzelziehen, hat der NV40-Chip zudem Zusatz-Hardware. Normalisierung braucht man oft im Zusammenhang mit Bumpmapping. Ein normales NRM kostet ca. zwei Takte. Die NRM_PP-Unit kann aber – in Partial Precision – parallel zu den Shader Units auch normalisieren. Das entlastet die Shader Units und verschnellert die Ausführung des gesamten Pixelshaders. Man muss dann zwar mit _PP leben, aber bedenkt man, dass man vom Transistorcount her für eine FP32-NRM-Unit reichlich zwei NRM_PP-Units bekommt, lässt sich spekulieren, dass auch der kommende R520-Chip dedizierte _PP-Units eingebaut haben könnte.
Es gibt hierbei sicherlich keinen "besten" Weg. Sofern _PP die Bildqualität nicht beeinträchtigt, sollte das Flag gesetzt werden, denn GeForce-Karten profitieren davon. ATIs Radeons gewinnen daraus keinen Vorteil (der Treiber ignoriert das Flag), aber bieten dafür eine hervorragende Grundleistung. Und in jedem Fall ist es unverständlich, wenn bezüglich der Filterqualität die Rechengenauigkeit von den IHVs immer weiter nach unten gedrückt wird, bei den Shadern jedoch Optimierungen, deren zusätzliche Ungenauigkeit nur eher theoretischen Bedeutung haben, nicht genutzt bzw. sogar teilweise schlechtgemacht werden.