PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Gratis FP16 Normalize bei NV4x


Corrail
2004-04-28, 16:35:43
Hello!

Ich hab da mal was von einem "gratis" FP16 Normalize bei der NV4x Architektur gelesen. Wie "gratis" ist der? Hab ich den pro Takt? Oder auf eine bestimmte Anzahl von Vektoren beschränkt?

Danke im Vorraus

Xmas
2004-04-28, 17:50:24
Gratis ist eigentlich das falsche Wort. Man könnte sagen, der NV40 hat eine spezielle Einheit für NRM_pp. Also ein NRM_pp pro Takt.

Insgesamt sieht es scheinbar so aus:

SU0 kann:
- NRM_pp + TEX
- NRM_pp + MUL4
- NRM_pp + MUL3 + MUL1
- NRM_pp + MUL2 + MUL2
- NRM_pp + SF
sowie Modifier /2, *2, *4, *8, bx2

SU1 kann:
- MUL4 | MAD4 | DOT4
- (MUL3 | MAD3 | DOT3) + (MUL1 | MAD1)
- (MUL2 | MAD2 | DOT2) + (MUL2 | MAD2 | DOT2)
sowie Modifier /2, *2, *4, *8, bx2

Wobei die Zahlen hinter den Operationen die Anzahl der beteiligten Vektorkomponenten angibt.

Corrail
2004-04-28, 18:01:14
Cool, danke.
Aber so gesehen ist der FP16-Normalize "gratis". Weil egal was man bei SU0 macht, man hat einen FP16-Normalize.

Brauch ich dann für einen FP32-Normalize 2 Takte (also 2 x NRM_pp) oder muss ich das wieder über dot(), inv_sqrt() und mul machen?

Xmas
2004-04-28, 18:46:54
Letzteres.

Corrail
2004-04-28, 20:05:06
Oki, gut zu wissen.
Danke dir!

aths
2004-04-29, 09:46:20
Ich meine irgendwo gelesen zu haben, dass ein full precision NRM nur 1 Takt brauchen würde. Finde jetzt leider die Quelle nicht.

edit: Ich sehe gerade, das ist absurd. Man müsste die Units auch andersrum schalten können, so dass FPU#2 vor FPU#1 liegt. Man braucht nun mal das DP, bevor man RSQ ansetzen kann.

Demirug
2004-04-29, 10:34:30
Original geschrieben von aths
Ich meine irgendwo gelesen zu haben, dass ein full precision NRM nur 1 Takt brauchen würde. Finde jetzt leider die Quelle nicht.

edit: Ich sehe gerade, das ist absurd. Man müsste die Units auch andersrum schalten können, so dass FPU#2 vor FPU#1 liegt. Man braucht nun mal das DP, bevor man RSQ ansetzen kann.

Es geht sozusagen virtuel in einem Takt. Man braucht zwar 2 Takte aber in jedem davon wir nur der halbe Pixelprozessor belegt. Findet man also noch Befehle die man in die freien Plätze drücken kann passt das mit dem einen Takt schon.

aths
2004-04-29, 13:35:09
Original geschrieben von Demirug
Es geht sozusagen virtuel in einem Takt. Man braucht zwar 2 Takte aber in jedem davon wir nur der halbe Pixelprozessor belegt. Findet man also noch Befehle die man in die freien Plätze drücken kann passt das mit dem einen Takt schon. Das wird wohl so sein, ja.

Natürlich ist es schön, dass die Pipe so flexibel ist. Auf der anderen Seite wird es ein Heidenaufwand sein, die NV40-HW wirklich auszulasten. Schöner wäre es, wenn Unit 1 auch MAD / DP beherrschen würde und die SFU-Logik quasi "frei platzierbar" wäre. Natürlich würde das die Pipe weiter verkomplizieren.

Sehe ich das falsch, oder kann man sagen, dass ein NRM_PP zwar ganz nett ist, für wirklich gute Bumpmapping-Effekte aber ein FP32-NRM anzuraten wäre? (Bzw. FP24)

Demirug
2004-04-29, 13:45:41
Original geschrieben von aths
Das wird wohl so sein, ja.

Natürlich ist es schön, dass die Pipe so flexibel ist. Auf der anderen Seite wird es ein Heidenaufwand sein, die NV40-HW wirklich auszulasten. Schöner wäre es, wenn Unit 1 auch MAD / DP beherrschen würde und die SFU-Logik quasi "frei platzierbar" wäre. Natürlich würde das die Pipe weiter verkomplizieren.

Frei verschieben kannst du vergesen sowas macht die Pipe viel zu lang.

Sehe ich das falsch, oder kann man sagen, dass ein NRM_PP zwar ganz nett ist, für wirklich gute Bumpmapping-Effekte aber ein FP32-NRM anzuraten wäre? (Bzw. FP24)

Wenn man bedenkt das die Bumpmaps in der Regel nur mit 8 Bit pro Kanal gespeichert sind muss man sich IMHO schon fragen ob FP24/FP32 für den Lichtvektor da immer notwendig ist. Es spricht ja nichts dagegen beide Varianten zu haben und dann entsprechende auswahlen zu erlauben.

aths
2004-04-29, 14:40:51
Original geschrieben von Demirug
Wenn man bedenkt das die Bumpmaps in der Regel nur mit 8 Bit pro Kanal gespeichert sind muss man sich IMHO schon fragen ob FP24/FP32 für den Lichtvektor da immer notwendig ist. Es spricht ja nichts dagegen beide Varianten zu haben und dann entsprechende auswahlen zu erlauben. Dieses 8-Bit-BM glänzt nicht gerade mit Präzision. Das reicht für einige einfache Dot3-Effekte und ein wenig EMBM. Wenn schon BM, würde ich damit gerne feine, detaillierte Strukturen sehen. Und natürlich via dem Sichtvektor angepasstes Displacement aus der Textur sehen ("Offset Mapping".)

Das Dot3-BM im 2000-er 3DMark fand ich noch faszinierend, aber man ist so schnell verwöhnt ;(

Demirug
2004-04-29, 15:16:59
Original geschrieben von aths
Dieses 8-Bit-BM glänzt nicht gerade mit Präzision. Das reicht für einige einfache Dot3-Effekte und ein wenig EMBM. Wenn schon BM, würde ich damit gerne feine, detaillierte Strukturen sehen. Und natürlich via dem Sichtvektor angepasstes Displacement aus der Textur sehen ("Offset Mapping".)

Das Dot3-BM im 2000-er 3DMark fand ich noch faszinierend, aber man ist so schnell verwöhnt ;(

Mir fällt jetzt aber spontan kein Spiel ein das mehr als 8Bit Bumpmaps nutzt. Du darfst mich aber gerne erleuchten.

Xmas
2004-04-29, 16:17:43
Original geschrieben von Demirug
Es geht sozusagen virtuel in einem Takt. Man braucht zwar 2 Takte aber in jedem davon wir nur der halbe Pixelprozessor belegt. Findet man also noch Befehle die man in die freien Plätze drücken kann passt das mit dem einen Takt schon.
Sollten es nicht virtuell 1,5 Takte sein? (mal abgesehen von Co-Issue wenn man nur Vec3-NRM benötigt)
DOT3 in SU1
RSQ in SU0
MUL3 in SU1

Oder hab ich da was falsch verstanden und SF ist parallel zum MUL in SU0 möglich?

ow
2004-04-29, 16:39:21
.

aths
2004-04-29, 16:49:52
Original geschrieben von ow
Fand ich nicht so faszinierend, weil da gar kein Dot3 BM drin ist.:D Vielleicht meinst du ja EMBM. IIRC zeigte der 99-er Emboss und EMBM und der 2000-er Dot3 und EMBM.

aths
2004-04-29, 16:50:38
Original geschrieben von Demirug
Mir fällt jetzt aber spontan kein Spiel ein das mehr als 8Bit Bumpmaps nutzt.Mir auch nicht.

Mir fällt jetzt aber spontan kein Spiel ein, wo mich das Bumpmapping wirklich vom Hocker riss.

Demirug
2004-04-29, 18:05:43
Original geschrieben von Xmas
Sollten es nicht virtuell 1,5 Takte sein? (mal abgesehen von Co-Issue wenn man nur Vec3-NRM benötigt)
DOT3 in SU1
RSQ in SU0
MUL3 in SU1

Oder hab ich da was falsch verstanden und SF ist parallel zum MUL in SU0 möglich?

Ja, die SF Units sitzen vor den MULs in der SU0. Deswegen kann die SU0 ja zum Beispiel auch einen DIV in einem Takt durchführen. Das war im Prinzip auch schon im Shader-Core des NV30 so nur weiss ich nicht ob es dafür ein entsprechendens Instruktionswort gab.

Quasar
2004-04-29, 18:27:03
Original geschrieben von aths
IIRC zeigte der 99-er Emboss und EMBM und der 2000-er Dot3 und EMBM.

Nope, grad nachgeschaut. ow hat Recht. Erst der 2001er bot DOT3.

ow
2004-04-29, 18:34:34
.

Xmas
2004-04-29, 18:58:08
Original geschrieben von Demirug
Ja, die SF Units sitzen vor den MULs in der SU0. Deswegen kann die SU0 ja zum Beispiel auch einen DIV in einem Takt durchführen. Das war im Prinzip auch schon im Shader-Core des NV30 so nur weiss ich nicht ob es dafür ein entsprechendens Instruktionswort gab.
Also nun SU0:
- NRM_pp + TEX
- NRM_pp + SF + MUL4
- NRM_pp + SF + MUL3 + MUL1
- NRM_pp + SF + MUL2 + MUL2
sowie Modifier /2, *2, *4, *8, bx2
?

Demirug
2004-04-29, 19:39:00
Original geschrieben von Xmas
Also nun SU0:
- NRM_pp + TEX
- NRM_pp + SF + MUL4
- NRM_pp + SF + MUL3 + MUL1
- NRM_pp + SF + MUL2 + MUL2
sowie Modifier /2, *2, *4, *8, bx2
?

So einfach ist das leider nicht.

Lassen wir den FP16Nrm erst mal weg. SU0 kann bis zu zwei Anweisungen pro Takt ausführen. Dabei handelt es sich aber um Anweisungen aus einem NV40 eigenen Befehlssatz. Dieser enthält zum Teil Anweisungen die es nicht als DX-PS Anweisung gibt. Dort muss man das gleiche durch mehrer Anweisungen zusammensetzten. DIV ist hier ein Beispiel. Bei DX braucht man dafür einen RCP+MUL also zwei Anweisungen. Am Ende der SU0 gibt es nun noch eine Crossbar welche die Ergebnisse der Anweisungen verteilt. Ein Ergebniss kann zur TMU als Koordinaten geschickt werden und das andere geht über einen FIFO zur SU1. Der FIFO sorgt dafür das das Texturergebniss und die restlichen Werte syncron bei SU1 ankommen.

Eine Texturoperation ist also für den NV40 eine Rechenoperation deren Ergebniss zur TMU geschickt wird. Gibt es allerdings nichts zu rechen muss der Texturbefehl sozusagen um einen NOP (bzw Mov) ergänzt werden welcher die Koordinaten einfach unverändert durch die SU0 schiebt.

Was nun den FP16Nrm angeht so habe ich den Verdacht das dieser gar nicht direkt von der SU0 ausgeführt wird sondern in dem FIFO.

Ich weiss das dies alles etwas der Darstellung von nVidia in den öffentlichen Dokumenten wiederspricht. Dort hat nVidia aber ein stark vereinfachtes Model benutzt weil es sonst sowieso keiner mehr versteht.

Zusammengefasst:

- NV40 führt bis zu 4 Instruktionen pro Takt und Pipe aus.
- Jeweils 2 Instruktionen müssen zusammen einen Vektor4 bilden.
- NV40 hat einen eigenen Instruktionssatz der nicht 1:1 auf den DX-PS Instruktionssatz abbildbar ist. Einen Teil der DX-PS Anweisungen muss er in 2 oder noch noch mehr interne Anweisungen zerlegen (z.B. LRP) dafür gibt es im Gegenzug aber auch Anweisungen die nur durch mehrer DX-PS Anweisungen dargestellt werden können.
-Eine Texturnaweisung beim NV40 stösst nicht nur das samplen an sondern kann auch noch eine Rechnung mit den Koordinaten enthalten.
- Es ist eine Texturanweisung pro Takt möglich. Diese geht von den 4 Gesamtanweisungen ab.

ScottManDeath
2004-04-29, 21:31:18
Ist dieses "mehrere DX PS Ops sind eine NV40 Op" und "manche DX PS Ops benötigen mehrere NV40 Ops" nicht ein Argument für einen Hochsprachencompiler im Treiber ala GLSL?

Zur Zeit muss der PS "Recompiler" im Treiber die Shader durchgehen und gucken ob er ein RCP/MUL Paar (vom fxc generiert) findet um dann eine native DIV Op zu generieren.

Wäre es da nicht effizienter das direkt aus der internen Repräsentation des HL Shaders zu machen?

Eine andere Möglichkeit wäre es jedem Vendor (oder einer Gruppe von Vendors) zu erlauben eigene PS "Versionen" mit OPs zu definieren mitsamt einem fxc target? Moment .... aber dann haben wir ja die gleiche Situation wie in OpenGL mit den NV_*_program Extensions. ;)


wenn es zu OT wird, bitte splitten

Demirug
2004-04-29, 21:44:35
Original geschrieben von ScottManDeath
Ist dieses "mehrere DX PS Ops sind eine NV40 Op" und "manche DX PS Ops benötigen mehrere NV40 Ops" nicht ein Argument für einen Hochsprachencompiler im Treiber ala GLSL?

Zur Zeit muss der PS "Recompiler" im Treiber die Shader durchgehen und gucken ob er ein RCP/MUL Paar (vom fxc generiert) findet um dann eine native DIV Op zu generieren.

Wäre es da nicht effizienter das direkt aus der internen Repräsentation des HL Shaders zu machen?

Eine andere Möglichkeit wäre es jedem Vendor (oder einer Gruppe von Vendors) zu erlauben eigene PS "Versionen" mit OPs zu definieren mitsamt einem fxc target? Moment .... aber dann haben wir ja die gleiche Situation wie in OpenGL mit den NV_*_program Extensions. ;)


wenn es zu OT wird, bitte splitten

Einen reinen Hochsprachencompiler im Treiber halte ich aus Gründen der Plannungssicherheit nach wie vor für zu gefährlich. Aber ich habe ja schon einmal einen Vorschlag für das Problem gemacht:

1. Ein Treiber muss die Assemblerschnittstelle für Shader unterstützen und sich auch an die Richtlinien der entsprechenden Version halten.

2. MS liefert einen Compiler welcher HLSL in Assemblershader umsetzten kann.

3. Die Runtime kann direkt HLSL Code entgegennehmen.

4. Ein Treiber kann optional eine HLSL Schnittstelle unterstützen.

Der Workflow würde dann wie folgt aussehen.

Wenn der Treiber HLSL direkt unterstützt bekommt er zuerst den HLSL Code übergeben. Kann er ihn verarbeiten bekommt man sein Shaderhandel und gut ist.

Kann der Treiber keine HLSL Shader direkt verarbeiten oder er lehnt den Shader ab prüft man ob er die für diesen HLSL-Shader mindestens erforderliche Shaderversion (kann man einmal im Vorfeld feststellen) unterstützt wird. Ist das nicht der Fall ist der Shader nicht verfügbar und man beginnt mit dem Fallback Shader das ganze Spiel von vorne. Ansonsten wird der Shader mit dem MS-Compiler verarbeitet und dem Treiber als Assembler Shader übergeben.

IMHO ist diese Lösung das beste aus beiden Welten.

ScottManDeath
2004-04-29, 22:22:33
Ok, hört sich plausibel an.
Plant MS etwas in dieser Richtung (DXNext)? Es wird wohl in der Zukunft immer schwerer möglich werden mit ps_x_y alle Architekturen unter einen Hut zu bekommen.

Der MS HLSL -> ASM Compiler wäre dann Teil der Runtime und nicht wie jetzt Teil von D3DX?

Xmas
2004-04-30, 15:11:34
Original geschrieben von Demirug
So einfach ist das leider nicht.


Zusammengefasst:

- NV40 führt bis zu 4 Instruktionen pro Takt und Pipe aus.
- Jeweils 2 Instruktionen müssen zusammen einen Vektor4 bilden.
- NV40 hat einen eigenen Instruktionssatz der nicht 1:1 auf den DX-PS Instruktionssatz abbildbar ist. Einen Teil der DX-PS Anweisungen muss er in 2 oder noch noch mehr interne Anweisungen zerlegen (z.B. LRP) dafür gibt es im Gegenzug aber auch Anweisungen die nur durch mehrer DX-PS Anweisungen dargestellt werden können.
-Eine Texturnaweisung beim NV40 stösst nicht nur das samplen an sondern kann auch noch eine Rechnung mit den Koordinaten enthalten.
- Es ist eine Texturanweisung pro Takt möglich. Diese geht von den 4 Gesamtanweisungen ab.
Dass das nicht so einfach ist, ist mir auch klar ;)

Ein Beispiel mit angeblich 7 Instruktionen pro Takt stammt ja von NVidia. Dabei werden IIRC zwei als Modifier auf die Mini-ALUs gelegt, ein NRM_pp, und vier MUL2 oder ähnliches.

Es geht mir hauptsächlich um die "Basisanweisungen" MUL/ADD/MAD/DOT, sowie die Spezialfunktionen RCP/RSQ/(SIN/COS). Dass LERP dann gleich MUL+MAD, oder DIV gleich RCP + MUL ist, ist mir auch klar. Ich will nur wissen, wieviel die Pipeline pro Takt kann, und wo die Grenzen sind.

Wenn eine Texturanweisung auch eine Rechnung mit den Koordinaten enthalten kann, heißt das dass ich z.B. RSQ - MUL - TEX in einem Takt in SU0 machen kann?
TEX belegt dann wohl so viele Komponenten, wie die Textur Dimensionen hat, oder immer 3?

Demirug
2004-04-30, 15:23:39
Original geschrieben von Xmas
Dass das nicht so einfach ist, ist mir auch klar ;)

Ein Beispiel mit angeblich 7 Instruktionen pro Takt stammt ja von NVidia. Dabei werden IIRC zwei als Modifier auf die Mini-ALUs gelegt, ein NRM_pp, und vier MUL2 oder ähnliches.

Ich habe die entsprechenden Folien leider nicht mehr da. IIRC war da eine Tex Anweisung dabei.

Es geht mir hauptsächlich um die "Basisanweisungen" MUL/ADD/MAD/DOT, sowie die Spezialfunktionen RCP/RSQ/(SIN/COS). Dass LERP dann gleich MUL+MAD, oder DIV gleich RCP + MUL ist, ist mir auch klar. Ich will nur wissen, wieviel die Pipeline pro Takt kann, und wo die Grenzen sind.

Da nVidia das genaue Diagramm noch nicht rausgerückt hat kennt man die genauen Grenzen nicht. Vorallem liegt dann immer noch zwischen Theorie und Praxsis der Shadercompiler im Treiber.

Wenn eine Texturanweisung auch eine Rechnung mit den Koordinaten enthalten kann, heißt das dass ich z.B. RSQ - MUL - TEX in einem Takt in SU0 machen kann?

Ja, und der zweite Teil von SU0 kann theoretisch noch was anderes tun.

TEX belegt dann wohl so viele Komponenten, wie die Textur Dimensionen hat, oder immer 3?

Das ist eine gute Frage. Wenn ich es richtig verstanden habe nimmt sich die Texturanweisung nur soviel wie sie braucht aber 100% sicher bin ich da auch nicht.

Xmas
2004-04-30, 16:03:51
Mal ein kleines Diagramm wie ich mir SU0 vorstelle.

Die Breiten Pfeile sollen darstellen dass hier aus dem Register File gelesen wird.
SF nimmt als Input einen Skalar und gibt einen Skalar aus.
Der "große" MUX wählt dann aus was an die vier MUL-Einheiten weitergegeben wird. Dazu kann er aus verschiedenen Registern (wie viele?) wählen, sowie die Werte 0, 1 und das Ergebnis von SF verwenden. Die MUL-Einheiten multiplizieren logischerweise immer. Der "Split" ergibt sich nur daraus, welche Eingabewerte sie erhalten.
Der Crossbar entscheidet dann, ob ein Vec3-Ergebnis an die TMU geht oder nicht.

Eine wichtige ungeklärte Frage ist, wieviele Register bzw. Komponenten können pro Takt gelesen werden, und wieviel kann unverändert an SU1 weitergereicht werden.

SU0 kann ja maximal 9 Komponenten verarbeiten. Aber nur, wenn für SF noch ein "Nebenpfad" vorhanden ist, über den das Ergebnis parallel zu den MUL weitergereicht wird. Ansonsten müsste das SF-Ergebnis durch eine MUL-Einheit weitergereicht werden, womit SU0 nur noch 8 Komponenten verarbeiten kann.

Xmas
2004-04-30, 16:16:22
Somit erwarte ich pro Takt folgendes tun zu können:

// SF - MUL - TEX
SF b.xyzw, a.x
MUL d.xyzw, c.xyzw, b.xyzw
TEX e.xyzw, d.xyz

// SF + MULx Split
SF b.x[yz], a.x[yz]
MUL e.[yz]w, d.[yz]w, c.[yz]w

// SF-MUL + MULx Split
SF b.x[yz], a.x[yz]
MUL d.x[yz], c.x[yz], b.x[yz]
MUL g.[yz]w, f.[yz]w, e.[yz]w

// MUL3 + MUL1 Split
MUL c.x, b.x, a.x
MUL f.yzw, e.yzw, d.yzw

// MUL2 + MUL2 Split
MUL c.xy, b.xy, a.xy
MUL f.zw, e.zw, d.zw

Wobei die Swizzle/Write Masks nur die Anzahl der möglichen Komponenten angeben.