PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Lösung für das Branch,Loop Problem bei 3.0 Pixelshader?


Demirug
2003-06-20, 20:58:47
Intel hat uns mit dem Pentium 4 unter anderem eines gelehrt. Eine lange Pipelines erlaubt hohe Taktraten aber dafür muss der Chip weit vorraus denken und wenn er daneben tippt wird das löschen und neu aufsetzten der Pipeline teuer.

Grafikchips kannten dieses Problem bei den Shadern bisher eigentlich nicht. Ein Shaderprogramm wurde von vorne bis hinten durchlaufen dynamische änderungen im Programmablauf gab es nicht. Die 3.0 Shader fordern aber nun genau dieses Feature.

Die Konsequezen die sich daraus ergeben sind gross. Bisher konnten sich die Pixelpipelines durchaus einige Resourcen teilen. So rechnet ja zum Beispiel ein NV30 immer einen 2*2 Pixelblock am stück. Für alle Pixel in einem solchen Block wird zur gleichen Zeit die gleiche Anweisung ausgeführt, aus der gleichen Texture gesamplet (dabei der gleiche AF-Level benutzt) usw. Das alles kann aber nur dann uneingeschränkt funktionieren wenn für alle Pixel der gleiche Code ausgeführt wird. Bei den PS 3.0 kann das nicht mehr zwingend erfüllt werden.

Was also tun? Jede Pipelinesstufe die wieder gelöscht werden muss kostet Füllrate/Rechenleistung und davon hat man ja niemals genügend. zeckensack schlug einmal vor das man das ganze wie im Itanium lösen könnte. Bei einer Entscheidung werden erst einmal beide codepfade ausgeführt aber von dem der nicht der richtige war werden die ergebnisse einfach verworfen. Damit wäre das Problem das man die Pipeline löschen muss definitive vom Tisch. aber bei einem Shader welcher zwei gleich lange alterntive Codepfade hat würde man damit 50% der Leistung mit arbeit verbraten die dann verworfen wird. Das kann es doch nicht sein, oder?

Im Laufe dieses Tages kamm mir im Zusammenhang mit der R420 und PS 3.0 sowie der NV3X Pipeline Diskussion eine Idee.

Einen Pixelcache/F-Buffer zur Lösung dieses Problems einzusetzten. Wie funktioniert das ganze nun.

Gehen wir davon aus das wir einen Bufferspeicher für 100 Pixel haben.

Unser Beispielshader soll folgenden Aufbau haben.


Op-block 1

if (irgendwas)
Op-block 2
else
Op-block 3

Op-block 4



1. Schritt.
Poswahr = 0;
Posfalsch = 99;

Für die nächsten 100 Pixel welche vom Trisetup kommen

Führe OpBlock 1 aus.

Ist irgendwas = wahr
Speichere Pixel an Position Poswahr
Poswahr++
sonst
Speichere Pixel an Position Posfalsch
Posfalsch--

2. Scritt.
Für die Pixel von Position 0 bis Poswahr-1
Führe OpBlock 2 aus
aktualisere Pixeldaten im cache

3. Schritt.
Für die Pixel von Position Posfalsch bis 99
Führe OpBlock 3 aus
aktualisere Pixeldaten im cache

4. Schritt:
Für die Pixel von Position 0 bis 100
Führe OpBlock 4 aus
aktualisere Pixeldaten im cache

5. Schritt:
Für die Pixel von Position 0 bis 100
In den Framebuffer damit


Während im 5 Schritt der Pixelcache wieder freigebene wird kann man in gleichzeitig schon wieder mit den nächsten 100 Pixel durch Schritt 1 füllen. Dafür müsste man das Auslesen mit dem Einschreiben syncroniseren. Der übergang zwischen den Schritten läst sich sicherlich auch stossfrei realisieren. Also wenn der letzte der 100 Pixel aus schritt 1 die Pipeline betritt könnte im nächsten Takt schon der erste Pixel von Schritt 2 eingebracht werden.

Der Vorteil dieser Technik wäre ein minimaler Verlust von Füllrate (im besten Fall 0) in Verbindung mit dynamische Codefolgend.

Für Loops gilt im Prinzip das gleiche. Man führt immer einen Durchlauf aus und speichert die Information wie oft ein Pixel noch die Runde drehen muss. Sobald alle Pixel alle Durchlaufe abgeschlossen haben macht man mit dem nächsten Packet weiter. Auch hier läst sich das ganze weitgehend stossfrei realisieren.

ATI könnte das ganze durchaus mit der R350 F-Buffer Technik realiseren und die NV3x Pipelines sollte mit leichten änderungen ebenfalls fit dafür gemacht werden können.

zeckensack
2003-06-20, 21:46:56
:D

http://home.t-online.de/home/zsack/brot.zip

;calculate four mandelbrot samples with single precision SSE instructions
;samples are arranged in a 2x2 block, two real/img parts
;are taken from the argument pointers, and mixed and matched
;prototype:
;void x86_sse_mandel_2x2(const float* r,float* i,uint* results,uint max_it);

_x86_sse_mandel_2x2:
PUSH EAX
PUSH EDI

EMMS
XORPS xmm0,xmm0 ;z.r
XORPS xmm1,xmm1 ;z.i
XORPS xmm7,xmm7 ;_float_ iteration counter
MOV EDI,[ESP+16] ;get two imaginary parts
MOVLPS xmm5,[EDI]
SHUFPS xmm5,xmm5,80 ;shuffle 'n dupe 'em
MOVUPS xmm6,[one_single] ;counter increment
MOVUPS xmm4,[four_single] ;termination constraint

MOV EDI,[ESP+12] ;get pointer to real parts
;of complex params (no SSE registers left ...)
MOV EAX,[ESP+24] ;get max_it
.one_it:
;check constraint
;square z
MOVAPS xmm3,xmm1
MULPS xmm1,xmm0
MULPS xmm0,xmm0 ;get scalar magnitude of z, real^2 ...
MULPS xmm3,xmm3 ;+ img^2
MOVAPS xmm2,xmm0
ADDPS xmm2,xmm3
CMPLTPS xmm2,xmm4 ; <4.0?
ADDPS xmm1,xmm1
ANDPS xmm6,xmm2 ;increment counter if
;constraint hasn't been hit at least once
ADDPS xmm7,xmm6

SUBPS xmm0,xmm3

MOVLPS xmm2,[EDI] ;add c (real)
MOVLHPS xmm2,xmm2
ADDPS xmm0,xmm2
ADDPS xmm1,xmm5 ; (imaginary)

DEC EAX ;check against maximum iterations
JZ .early_out

TEST EAX,15 ;every 16 iterations, check
;whether the increments are still live
JNZ .one_it
MOVHLPS xmm2,xmm6
ORPS xmm2,xmm6
MOVAPS xmm3,xmm2
SHUFPS xmm3,xmm3,1
ORPS xmm2,xmm3
XORPS xmm3,xmm3
COMISS xmm2,xmm3
JNZ .one_it

.early_out:
MOV EDI,[ESP+20]
CVTPS2PI mm0,xmm7
MOVHLPS xmm7,xmm7
CVTPS2PI mm1,xmm7
MOVQ [EDI],mm0
MOVQ [EDI+8],mm1
EMMS
POP EDI
POP EAX
RETN

Ich habe hier 'emulierte' predication verwendet. Wie du siehst, sind damit auch dynamische und ungleiche Loop-Counts zwischen parallel durchgekauten Daten lösbar. Natürlich ist mein if/else nicht ausbalanciert, der eine Pfad ist wesentlich komplexer als der andere ...

Ich gebe aber folgende Punkte zu bedenken: parallele Pipelines sollen primär erstmal nur schneller sein als skalare Einheiten. Solange Parallelarbeit nicht langsamer ist, haben wir vielleicht eine suboptimale Lösung, aber kein echtes Problem. Es besteht weiterhin ein Gewinn durch Parallelisierung, Good Thing(tm).
Durch predication muß man zwei Zweige ausführen, das ist korrekt. Dadurch ergibt sich nun die neue Möglichkeit, diese beiden Zweige auch noch parallel auszuführen. Das ist auf jeden Fall ein Zugewinn auf x86-CPUs, wo dependency chains idR verhindern, daß alle Ops sofort verlustfrei ausführbar sind, obwohl noch Ausführungsressourcen frei sind. Ich kann durch diese Technik also 'pipeline bubbles' ausfüllen, und bekomme damit Teile der zusätzliche Rechenleistung quasi geschenkt.
Ich weiß nicht in welche Richtung sich Shader-HW entwickeln wird, ob parallele, für unterschiedliche Aufgaben ausgelegte Recheneinheiten pro ALU-Block kommen werden, oder nicht. Auf der Haben-Seite ist mit register combiner-HW diese Technik innerhalb der gegebenen Limitationen schon seit vielen Jahren machbar (und erfüllt ihren Zweck).
Das beste zum Schluß:
If/else-Predication braucht keine branches. Branches sind die teuersten Instruktionen die es überhaupt gibt. Es gibt in x86-Prozessoren nicht umsonst keine andere Klasse von Befehlen, die derart viel dedizierte Hardware verschlingt wie branches.
If/else mit branches zu lösen ist IMO der schlechteste Ansatz den es gibt. Branches braucht man nur für Loops, und auch dort kann predication durch 'Ansammeln' der Konditionale helfen, die Häufigkeit der branches zu reduzieren. Meinen Schleifencode oben würde ich für einen 2.0er Shader zB achtfach abrollen, und den Branch dann setzen. Somit habe ich mit einem einzigen Branch-Befehl acht Schleifendurchläufe für vier parallele Pixel erledigt. 32 für 1.
Versuch das mal ohne predication ...
Der Verschnitt der dabei zwangsläufig entsteht überwiegt bei weitem nicht die enormen Zugewinne in der Parallelisierung.



edit: Code-Kommentare umformatiert, um das ganze schmaler zu machen, Farben ...

Demirug
2003-06-20, 22:10:37
Zecki, ich glaube wir haben aneinader vorbei geredet. Ich streite ja gar nicht ab das auf einer CPU predication oft eine gute Sache ist aber in einem Grafikchip empfinde ich sie für mehr als ein paar wenige Instruktionen als reine Resourcenverschwendung.

Wenn ein Shader aus 101 Anweisungen besteht. 1 Bedingung und jeweils 50 Instruktionen in jedem Zweig. Mit Predication sind das pro Pixel 101 Instruktionen die ausgeführt werden müssen. Führt man nur das was wirklich notwendig ist aus kommt man nur auf 51 was fast nur noch die hälfte ist. Die eingesparten Takte sollten sich in eine erhebliche steigerung der Performance umsetzten lassen.

Du hast jetzt den Vorschlag gemacht die Pipeline so aufzubohren das man beide Pfade parrallel abarbeitet. Die dafür notwendigen Transitoren würde ich aber lieber als zusätzliche ALU in der Pipeline sehen weil man davon auch ohne Branchcode etwas hat.

Auch das Aufrollen von Schleifen ist im Prinzip eine gute Idee aber auch hier komme ich wieder mit dem Punkt das man Leistung verschenkt wenn man zum Beispiel 8 fach aufrollt und dann im Durchschnitt jeder Pixel die schleife nur 4 mal durchläuft.

Das Hauptproblem bei den branchs ist, und ich denke da sind wir uns einig, das man entweder die Pipeline blockieren muss bis man den Wert hat aufgrund dem man die Entscheidung treffen muss oder erst mal raten muss und die Gefahr eingeht die Pipeline rücksetzten zu müssen.

Meine überlegung war ja nun genau diese Problem dadurch zu eliminieren das man die Pipeline gar nicht in die verlegenheit bringt auf eine Wert zur Entscheidung warten zu müssen. Wenn man an genau der Stelle wenn die Entscheidung getroffen werden soll das bearbeiten unterbricht und den Pixel zwischenspeichert hat man ja an der Stelle in der Pipeline an der gespeichert werden soll den Entscheidungswert und kann abhängig davon in einen unterschiedlichen Buffer-bereich speichern.

Bei einer CPU würde ich das ganze niemals vorschlagen weil man dort ja gar nicht genügend Bandbreite für dieses Spiel hat aber bei einem Grafikchip könnte man das Design entsprechned auslegen das man einen Cache im Chip für genügend Pixel hat.

Der Namenlose
2003-06-20, 23:15:24
Was soll diese ganze Konstruktion eigentlich bringen? Das einzige was gespart wird ist ein bischen Logik für die unterschiedliche Ablaufsteurung bei in den Pixelpilines. Aber im Vergleich zum Rest ist das nicht so viel.
Und die Latenzen sind bei weitem nicht so dramatisch wie auf einer CPU. Der Code ist komplett im internen Cache und mit Sicherheit in einer einfach zu verabeitenden Form. Die VectorUnits auf der Ps2 haben eine Latenz von 2 Cyclen. Das sollte auf einer GPU mit PS3.0 eigentlich auch nicht viel anders sein. Ein größeres Latenzproblem sehe ich da eher bei den (dependend) Texturereads. Das ist die einzige Stelle, an der externer Speicher gelesen werden kann und damit keine konkrete Aussage über die Geschwindigkeit vorliegt.

Ich weiß ja nicht genau, wie ein aktuelles Hardware-Design momentan aussieht. Die Spezifikationen sehen zwar keine komplett freie Programmierbarkeit vor, allerdings kann man bei der Implementierung aus den Einschränkungen kaum noch wirklich Einsparungen realisieren (im Vergleich zu den TextureCombinern).
Ein typisches FPU Design (und auch die VectorUnits der PS2) sieht für die normalen Befehle 4 Takte Latenz bei Befehl pro Takt vor. Für Grafikhardware, die meist wenig Befehle aber mit hoher Abhängigkeit (die auch nicht wegoptimiert werden kann) ist das ungüstig. Man könnte aber ähnlich wie bei Hyperthreading, ein Rechenwerk mit mehreren Kontrolleinheiten+Registerbänken benutzen. D.h. 4 Pixel werden gleichzeitig von einer Einheit bearbeitet, wobei alle 4 Takte ein Befehl von einer Pixelpipline fertig wird. 2Ghz ist loker drin (siehe CPUs), durch 4 macht die für Grafikkarten typischen 500Mhz. Eventuell kann man auch noch ein anderes Verhältnis wählen.
Das die Pixel unterschiedlich lange benötigen, sollte auch kein Problem sein, das man ja immer nachfüllen kann, wenn einer fertig ist.

zeckensack
2003-06-20, 23:38:14
Original geschrieben von Demirug
Zecki, ich glaube wir haben aneinader vorbei geredet. Ich streite ja gar nicht ab das auf einer CPU predication oft eine gute Sache ist aber in einem Grafikchip empfinde ich sie für mehr als ein paar wenige Instruktionen als reine Resourcenverschwendung.

Wenn ein Shader aus 101 Anweisungen besteht. 1 Bedingung und jeweils 50 Instruktionen in jedem Zweig. Mit Predication sind das pro Pixel 101 Instruktionen die ausgeführt werden müssen. Führt man nur das was wirklich notwendig ist aus kommt man nur auf 51 was fast nur noch die hälfte ist. Die eingesparten Takte sollten sich in eine erhebliche steigerung der Performance umsetzten lassen.... wobei sich die Frage stellt "wie teuer wären im Vergleich echte branches?" :)

Daß die Frage berechtigt ist, darüber sind wir uns ja einig. Ich schmeiße Ausführungsressourcen auf das Problem, und du schmeißt Bandbreite und Puffer (on chip?) auf das Problem. Mein Urteilsvermögen ist möglicherweise durch den x86-Background getrübt, da könntest du Recht haben ;)
Dort hat man quasi immer irgendeine Ausführungseinheit frei, kein Wunder bei Taktraten, die um Faktor 15 über dem Speichertakt liegen ...

Aaaaber ...
Du hast jetzt den Vorschlag gemacht die Pipeline so aufzubohren das man beide Pfade parrallel abarbeitet. Die dafür notwendigen Transitoren würde ich aber lieber als zusätzliche ALU in der Pipeline sehen weil man davon auch ohne Branchcode etwas hat.Ich will keine dedizierte Einheit, die nur für predication nutzbar ist, nö. Ich will auch eine extra ALU. Mir schwebt ähnliches vor wie zB die Athlon-FPU. Man geht erstmal von einer einzelnen Einheit aus, die alles kann (und dementsprechend riesig ist). Wenn man nun den Durchsatz weiter steigern will, braucht man früher oder später mehr ALUs (weil man den Takt nicht mehr beliebig steigern kann). Dann stellt man aber fest daß es einfachere Einheiten auch tun, weil die 'fette' ALU die wenigen komplexen Instruktionen im Code auch alleine schafft.

Der Punkt ist jetzt, man kann damit unabhängige Anweisungsfolgen schneller abarbeiten (immer mindestens genauso schnell wie vorher), handelt sich aber bei Abhängigkeiten 'Blasen' in der Pipeline ein.
Die kann ich nutzen. Du nicht. Derjenige, der dedizierte Branching-Hardware fordert, bist also du :bäh2:

Ganz im Ernst, daß konditionale Sprünge in Shadern teuer sind sollte jedem bewußt sein, dementsprechend sollte man sie auch sparsam einsetzen. Auch dein Verfahren ist nicht frei, weil du diverse Umfüllaktionen der Pipeline machen mußt, die wieder Leerzyklen verursachen.

Auch das Aufrollen von Schleifen ist im Prinzip eine gute Idee aber auch hier komme ich wieder mit dem Punkt das man Leistung verschenkt wenn man zum Beispiel 8 fach aufrollt und dann im Durchschnitt jeder Pixel die schleife nur 4 mal durchläuft.Der Schnipsel oben ist (leider?) aus einem real existierenden Projekt, und wurde daraufhin geschrieben. Erfahrungsgemäß läuft diese Schleife viele tausend mal durch, deswegen ist für diesen speziellen Fall die Granularität angemessen.
Klar verliert man im Extremfall 25%, aber das ist weit entfernt vom Durchschnitt. Dafür gehen alle Daten, auf die die gleichen Instruktionen wirken sollen den gleichen Weg. Lokalität ahoi!
Was dieser Ansatz nämlich auch kann, ist das Teilen einer einzigen Kontroll-Logik für alle parallelen Pixel-Pipelines (entspräche Fetch/Decode/issue auf CPUs). Für deinen Ansatz muß man die Pipelines entkoppeln, da überall unterschiedliche Zweige laufen können. Entkoppelt man nicht, fährt man sich wider Leerzyklen ein. Vom Hardware-Aufwand nähern wir uns weiter an :D

Das Hauptproblem bei den branchs ist, und ich denke da sind wir uns einig, das man entweder die Pipeline blockieren muss bis man den Wert hat aufgrund dem man die Entscheidung treffen muss oder erst mal raten muss und die Gefahr eingeht die Pipeline rücksetzten zu müssen.'Speculative execution' wäre Raten. Ich möchte garnicht raten, sondern mit Gewalt vorgehen. Das klingt erstmal dämlich, dadurch erzeuge ich aber zumindest weiteren Input für einen guten Compiler (hrhr ...), der damit hoffentlich besser umgehen kann als Hardware. Mit etwas Glück kann man vielleicht sogar Gemeinsamkeiten in den beiden Sequenzen entdecken, skalare Ops in SIMD-Ops falten ...
Jedenfalls behaupte ich einfach mal ganz frech, daß 50+50+branch im Schnitt 70 Instruktionen ergibt, wenn man sie denn parallel ausführt.
Meine überlegung war ja nun genau diese Problem dadurch zu eliminieren das man die Pipeline gar nicht in die verlegenheit bringt auf eine Wert zur Entscheidung warten zu müssen. Wenn man an genau der Stelle wenn die Entscheidung getroffen werden soll das bearbeiten unterbricht und den Pixel zwischenspeichert hat man ja an der Stelle in der Pipeline an der gespeichert werden soll den Entscheidungswert und kann abhängig davon in einen unterschiedlichen Buffer-bereich speichern.Und was tust du, wenn zwei parallele Pipelines nach unterschiedlichen Laufzeiten mit ihren Puffern fertig sind?
[/frech]
Bei einer CPU würde ich das ganze niemals vorschlagen weil man dort ja gar nicht genügend Bandbreite für dieses Spiel hat aber bei einem Grafikchip könnte man das Design entsprechned auslegen das man einen Cache im Chip für genügend Pixel hat. Meine Antwort markiere ich jetzt mal als total OT:
Der Code oben konsumiert 16 Bytes input, und erzeugt 8 Bytes output (max_it ist eine Konstante). Die Schleife läuft mindestens mehrere hundert mal am Stück, bei aths schonmal mehrere Millionen mal. Bandbreite ist hier überhaupt kein Problem. Das Problem ist die maximale Ausnutzung der vorhandenen parallelen Recheneinheiten mit einer einzelnen Kontroll-Logik, und dafür habe ich ganz ernsthaft keine andere Lösung gefunden. Dein Verfahren kann ich leider nicht direkt in Software umsetzen - Hardware-Limitierung ;)

zeckensack
2003-06-20, 23:49:30
Ach so, Bonus-Zuckerl:
Der NV30 hat keine Branch-Hardware. Branches werden in predication-Manier ausgeführt ;)
(so gesehen am allseits beliebten 'kil')

Ich verbitte mir aber jeden Vergleich mit meinem Vorschlag, wenn es um die zu erwartende Performance geht :D

zeckensack
2003-06-21, 00:33:31
Original geschrieben von Der Namenlose
Was soll diese ganze Konstruktion eigentlich bringen? Das einzige was gespart wird ist ein bischen Logik für die unterschiedliche Ablaufsteurung bei in den Pixelpilines. Aber im Vergleich zum Rest ist das nicht so viel.
Und die Latenzen sind bei weitem nicht so dramatisch wie auf einer CPU. Der Code ist komplett im internen Cache und mit Sicherheit in einer einfach zu verabeitenden Form. Die VectorUnits auf der Ps2 haben eine Latenz von 2 Cyclen. Das sollte auf einer GPU mit PS3.0 eigentlich auch nicht viel anders sein. Ein größeres Latenzproblem sehe ich da eher bei den (dependend) Texturereads. Das ist die einzige Stelle, an der externer Speicher gelesen werden kann und damit keine konkrete Aussage über die Geschwindigkeit vorliegt.So sieht eine moderne CPU aus:
http://www.chip-architect.com/news/2003_03_06_Looking_at_Intels_Prescott.html

Man vergleiche die Größe der Ausführungseinheiten mit dem "bisschen Logik" für die Steuerung. Mich interessiert hier vor allem der Block 'Floating point and media' gegen 'Queue , schedule, dispatch'. Ich habe wirklich kein Interesse daran, daß Grafikchips die gleichen Maßnahmen ergreifen. Im Gegensatz zu x86-CPUs ist das auch nicht nötig, weil niemand außer dem Treiber den echten Assembler-Code zu gesicht bekommt. Da nehme ich lieber dankend Ausführungseinheiten, Textursampler und Cache.

OOE und der ganze Rattenschwanz hintendran, dann noch branch prediction, das alles dann unabhängig für jede Pixelpipeline und schon hast du einen Chip der zu zwei Dritteln aus Steuerlogik besteht.

Ich will nicht sagen daß x86-CPUs alle Designfehler sind, keineswegs, aber die Notwendigkeiten die zu diesen Designs geführt haben sind nunmal im Graka-Business nicht vorhanden. Das ist eine Chance für die Entwickler, jedenfalls empfinde ich das so :)

Übrigens denke ich auch nicht daß der direkte Vergleich mit CPUs fair ist, ich seh's aber eher anders herum: halbwegs moderne CPUs haben kaum noch Probleme mit Schlabbercode, Scheduling-Optimierungen und dergleichen erledigen sie einfach 'on the fly'. Wenn ich mit einem speziellen Verfahren selbst aus einem bereits total durchoptimerten HW-Design noch was rauskitzeln kann, dann muß das gleiche Verfahren (so weit es anwendbar ist) auf 'einfachen' Designs, wie es Grafikchips eben sind, auch etwas bringen.

Ich weiß ja nicht genau, wie ein aktuelles Hardware-Design momentan aussieht. Die Spezifikationen sehen zwar keine komplett freie Programmierbarkeit vor, allerdings kann man bei der Implementierung aus den Einschränkungen kaum noch wirklich Einsparungen realisieren (im Vergleich zu den TextureCombinern).Ich glaube die Vereinfachungen werden kommen, wenn die Pipelines in sich stärker parallel ausgelegt werden (=> mehrere Ops pro Takt pro Pipe). Warum ich das glaube, habe ich oben schon geschrieben :)
Ein typisches FPU Design (und auch die VectorUnits der PS2) sieht für die normalen Befehle 4 Takte Latenz bei Befehl pro Takt vor. Für Grafikhardware, die meist wenig Befehle aber mit hoher Abhängigkeit (die auch nicht wegoptimiert werden kann) ist das ungüstig. Man könnte aber ähnlich wie bei Hyperthreading, ein Rechenwerk mit mehreren Kontrolleinheiten+Registerbänken benutzen. D.h. 4 Pixel werden gleichzeitig von einer Einheit bearbeitet, wobei alle 4 Takte ein Befehl von einer Pixelpipline fertig wird. 2Ghz ist loker drin (siehe CPUs), durch 4 macht die für Grafikkarten typischen 500Mhz. Eventuell kann man auch noch ein anderes Verhältnis wählen.
Das die Pixel unterschiedlich lange benötigen, sollte auch kein Problem sein, das man ja immer nachfüllen kann, wenn einer fertig ist. Steuerlogik :|

Demirug
2003-06-21, 01:23:39
OK klappern wir die einzelen Punkte ab.

Blasen durch abhängigen umgehe ich durch eine serielle Anordnung meiner Einheiten. Damit kann ich auch abhängige Anweisungen mit maximalem Speed abarbeiten. OK meine Pipeline wird lang aber das ist mir ja wie gesagt egal weil ich ja innerhalb der Pipe keine Verzweigungen haben werde.

Und was tust du, wenn zwei parallele Pipelines nach unterschiedlichen Laufzeiten mit ihren Puffern fertig sind?
[/frech]

Das kann nicht passieren weil meine Pipelines alle immer genau den gleiche Programteil ablaufen lassen. Oder zur Verdeutlichung.

1. Alle Pipelines arbeiten den Codeteil vor der Verzweigung ab.
2. Alle Pipelines arbeiten den Codeteil für die erfüllte Bedingung ab.
3. Alle Pipelines arbeiten den Codeteil für nicht die erfüllte Bedingung ab.
4. Alle Pipelines arbeiten den Codeteil nach der Bedingung ab.

Bei Schritt 2 und 3 aber jeweils nur für die entsprechenden Pixel die am Ende von Schrit 1 entsprechend sortiert wurden.

Auch dein Verfahren ist nicht frei, weil du diverse Umfüllaktionen der Pipeline machen mußt, die wieder Leerzyklen verursachen.

Nein das gibt keine Leerzyklen weil man das Umprogrammieren der Pipe zusammen mit dem Einschieben der Daten tun kann. Also bei meinem Beispiel oben würde zusammen mit dem Einschieben des ersten Pixels von Schritt 2 auch das umprogrammieren der Pipeline erfolgen.

Deine CPU X86 Beispiele möchte ich ja gar nicht anzweifelen da du dort ja nicht die möglichkeit hattest die Hardware zu verändern musstest du das ganze ja über Software lösen.

Das Pixelcache verfahren hat auch noch einen weiteren Vorteil. Es reduziert den Einfluss der Länge von einzelnen Dependetlevel auf die Gesamtausführunszeit eines Pixelshaders. Sowohl bei ATI wie auch bei nvidia müssen Pixel die von Aritmetik auf Texturenanweisungen wechseln wieder zurück zum Anfang der Pipeline geschickt werden. Wenn die dependentlevel dann unterschiedlich lang sind gibt das Blasen ohne Ende. ATI warnt ausdrücklich vor diesem Problem. Würde man aber immer eine grössere Anzahl von Pixel mit dem gleichen Programmteil bearbeiten und dann mit all diesen Pixeln zum nächsten teil übergehen reduziert man diese Abhängkeit erheblich.

aths
2003-06-21, 02:06:51
zecki,

darf ich mal kurz OT werden: Wo lernt man so programmieren? ASM und dann auch noch SSE und so... habt ihr das im Studium oder beschäftigst du dich damit nebenbei? (Jedenfalls hoffe ich, dass du dir mit derartigen Kenntnissen deinen späteren Arbeitsplatz aussuchen kannst.)

Ailuros
2003-06-21, 04:00:30
Mir persoenlich waere eine Moeglichkeit den ganzen Shader-Wirrwarr in die zukuenftigen CPU´s umzuleiten lieber. CPU´s werden auch schneller kleiner.

Ich weiss schon jetzt was die Gegen-Argumente dafuer sein koennen und ich sehe auch ein dass es auch schwer realisierbar ist. Grafik Hartware wuerde in so einem Fall auch nicht billiger werden, da IHV´s die gewonnenen Transistoren fuer andere Implementationen verbrauchen koennten.

*zerbricht doofe Traumblase*

Sorry fuer die kleine Unterbrechung ;)

Demirug
2003-06-21, 07:18:11
Original geschrieben von Ailuros


Mir persoenlich waere eine Moeglichkeit den ganzen Shader-Wirrwarr in die zukuenftigen CPU´s umzuleiten lieber. CPU´s werden auch schneller kleiner.

Ich weiss schon jetzt was die Gegen-Argumente dafuer sein koennen und ich sehe auch ein dass es auch schwer realisierbar ist. Grafik Hartware wuerde in so einem Fall auch nicht billiger werden, da IHV´s die gewonnenen Transistoren fuer andere Implementationen verbrauchen koennten.

*zerbricht doofe Traumblase*

Sorry fuer die kleine Unterbrechung ;)

Ja aber GPUs werden derzeit schneller schneller als CPUs. Das andere Problem ist nach wie vor die Bandbreite. Und zu guter letztz darf man natürlich auch nicht vergessen das in so einer GPU verdammt viel Rechenpower steckt. Wenn ich jetzt noch daran denke das trotz mächtiger Grafikhardware Spiele immer noch CPU lastig sind sehe ich da ehrlich gesagt etwas schwarz. OK ein Teil der CPU lastigkeit kommt vom übertragen der Daten/Anweisungen zur Grafikhardware aber wenn die CPU die Sachen selber ausführen müsste wäre sie auch nicht schneller.

nehmen wir aleine mal den R300. Die 4 Vertexshader entsprechen etwa 4 SSE2 Einheiten die 8 ALUs der Pixelshader sind dann nocmal 8 Stück. Das sind aleine schon 12 SSE2 Einheiten ohne den ganze Rest drumherum. CPUs takten zwar höher aber so hoch nun auch wieder nicht. Und dann muss man ja noch bedenken das die Rechenpower eines R300 für richtige PS 3.0 Shader schon knapp werden wird. IMHO wird es keine Rückkehr zu Softwarerenderen geben.

zeckensack
2003-06-21, 07:26:02
Guten Morgen :)
Original geschrieben von Demirug
<...>
Das kann nicht passieren weil meine Pipelines alle immer genau den gleiche Programteil ablaufen lassen. Oder zur Verdeutlichung.

1. Alle Pipelines arbeiten den Codeteil vor der Verzweigung ab.
2. Alle Pipelines arbeiten den Codeteil für die erfüllte Bedingung ab.
3. Alle Pipelines arbeiten den Codeteil für nicht die erfüllte Bedingung ab.
4. Alle Pipelines arbeiten den Codeteil nach der Bedingung ab.

Bei Schritt 2 und 3 aber jeweils nur für die entsprechenden Pixel die am Ende von Schrit 1 entsprechend sortiert wurden.Das ist mir jetzt ziemlich peinlich, da habe ich dich irgendwie total mißverstanden. Ich hatte irgendwie in der Birne, daß paralleles flow control auch immer parallele Steuerung erfordert.

Wenn man die feste Zuordnung der Fragmente zu den einzelnen parallelen Pfaden beim branch aufhebt, dann hat man das Problem natürlich nicht.

Da bleibt mir jetzt nur noch zu sagen, daß ich mich geschlagen gebe ;)

Btw, OT, hier mal was lustiges, was mir Teile meines Schönheitsschlafs geraubt hat: :| (http://www.opengl.org/discussion_boards/ubb/Forum7/HTML/000392.html) <- klickbarer Smilie

zeckensack
2003-06-21, 07:34:18
Original geschrieben von aths
*schmeichel*aths, ich möchte dich darauf hinweisen, daß es mir verdammt schwer fällt auf solche Postings normal zu antworten, ohne psychische Schäden davonzutragen ;)

An der Uni lernt man jedenfalls aus meiner Sicht der Dinge nicht wirklich das Programmieren, schon garnicht in Assembler. Überhaupt habe ich an der Uni bisher nicht besonders viel von bleibendem Wert gelernt. Das mag einer der Gründe sein, warum meine Studier-Motivation nicht so groß ist wie sein könnte.

Aber danke für den guten Wunsch :)

Demirug
2003-06-21, 07:37:01
Original geschrieben von aths
zecki,

darf ich mal kurz OT werden: Wo lernt man so programmieren? ASM und dann auch noch SSE und so... habt ihr das im Studium oder beschäftigst du dich damit nebenbei? (Jedenfalls hoffe ich, dass du dir mit derartigen Kenntnissen deinen späteren Arbeitsplatz aussuchen kannst.)

Man bringt es sich eben bei wie die meisten Dinge die etwas mit programmieren zu tun haben. Wenn man Assembler kann ist SSE auch nur noch ein Satz zusätzlicher Befehle (das soll Zeckis Leistung jetzt nicht abwerten).

Was das Job aussuchen Aufgrund von Assembler Kenntnissen angeht so muss ich dir sagen das diese Kenntnisse den meisten am Hintern vorbei gehen.

Assemblercode ist teuerer in der Entwicklung, teurer in der Wartung und tendenziel Fehleranfälliger. Alles Dinge die man nicht haben will. Also meidet man Assemblercode wir der Teufel das Weihwasser.

Sicher es gibt nach wie vor Firmen die Leute mit Assemblerkenntnissen brauchen. Zum Beispiel firmen die Compiler entwickeln. Aber wenn man sich für diese Einsatzgebiete nicht interesiert...

Aber es ist ja nicht so das Zecki jetzt nur der Assemblercrack ist und sonst nichts drauf hätte. Er beherscht ja noch so viele andere Bereiche das er sicherlich für die meisten Jobs auf dem Gebiet mehr als Qualifiziert ist.

zeckensack
2003-06-21, 07:48:50
Original geschrieben von Demirug
Aber es ist ja nicht so das Zecki jetzt nur der Assemblercrack ist und sonst nichts drauf hätte. Er beherscht ja noch so viele andere Bereiche das er sicherlich für die meisten Jobs auf dem Gebiet mehr als Qualifiziert ist. :|

Ich glaub' ich geh mal ... kurz ... zum Supermarkt, oder so :|

Demirug
2003-06-21, 07:59:45
Original geschrieben von zeckensack
Guten Morgen :)
Das ist mir jetzt ziemlich peinlich, da habe ich dich irgendwie total mißverstanden. Ich hatte irgendwie in der Birne, daß paralleles flow control auch immer parallele Steuerung erfordert.

Wenn man die feste Zuordnung der Fragmente zu den einzelnen parallelen Pfaden beim branch aufhebt, dann hat man das Problem natürlich nicht.

Da bleibt mir jetzt nur noch zu sagen, daß ich mich geschlagen gebe ;)

Btw, OT, hier mal was lustiges, was mir Teile meines Schönheitsschlafs geraubt hat: :| (http://www.opengl.org/discussion_boards/ubb/Forum7/HTML/000392.html) <- klickbarer Smilie

Das war ja ein Teil der Übung das ich die parallität der Programmausführung soweit als möglich beibehalten wollte. Ansonsten wäre das ganze wie du ja schön festgestellt hast recht nutzloss gewesen.

OK es gibt dabei immer noch ein paar kritische Punkte aber da ich ja nicht David Kirk heise und ein schweine Geld für solche Überlegungen bekomme habe ich mir dafür noch keine Entgültige Lösung einfallen lassen.

Aber der vollständigkeit halber die Punkte die nicht abschliessend gelöst sind. Damit die Pipes im Moment parrallel beliben wird ja auf jeden Pixel bei jeder Texture die gleiche AF-Stufe angewant. Da die 2*2 Pixel ja nebeneinader liegen ist das ja auch kein Problem. Kommt es jetzt aber zu einer umsortierung ist die räumliche nähe nicht mehr zwangsläufig gegeben. Dadurch wird zum einen der Aufwand für das berechnen des AF-Levels und der Mipmap stufe höher weil man es ja dann wirklich per Pixel und nicht mehr per 2*2 Pixelblock machen kann. Der zweite Punkt ist das dabei entstehende unterschiedliche Laufzeiten für das sampeln durch waitstates wieder ausgeglichen werden müssen. Hat man also einen Pixel der nur 2xAF braucht und einen der 16xAF bekommt gleichzeitig in den Pipes muss der 2xAF aufgehalten werden bis der 16xAF Pixel auch fertig ist. Möglicherweise sollte man die Pixelpipeline auch an diesem Punkt noch einmal auftrennen.

Also:

Pixel aus dem Pixelcache holen
Sampeln
Pixel im Pixelcache aktualisieren.

Sobald dann 4 Pixel zur Verfügung stehen diese auf die ALUs loss lassen. In der Zwischenzeit könnten die TMUs die nächsten 4 Pixel vorbereiten. usw.

Oder um mal wieder meine gefürchtet ASCII-ART zum einsatz zu bringen


--<<--- P C --->>--
->-| I A |-<-
| ALU X C TMU |
-<-| E H |->-
-->>--- L E ---<<--


Das andere grössere Problem sehe ich bei den partial derivative.

Demirug
2003-06-21, 08:04:08
Original geschrieben von zeckensack
:|

Ich glaub' ich geh mal ... kurz ... zum Supermarkt, oder so :|

OT: OK das war jetzt wohl doch etwas Gemein von aths und mir. Ich weiss ja selbst wie das ist wenn man für Dinge gelobt wird die man für eigentlich nichts besonderes hält. Irgendwie ist mir das dann auch immer etwas peinlich. Deswegen gebe ich jetzt einfach mal weiter was mir dazu einmal gesagt wurde. "Nicht darüber nachdenken und einfach freuen." Der Tip mag ja gut sein aber immer schaffe ich das auch nicht.

aths
2003-06-21, 18:17:28
zs,

wenn ich das richtig lese (einzig aus dem Kommentar, allerdings) berechnest du in dieser Schleife Mandelbrot-Samples. Würdest du so nett sein, und diesen Code-Ausschnitt in einem extra-Thread erläutern, warum so und so, und was der Trick bei der Sache ist und so?



dr,

den Ansatz, TMU- und ALU-Logik gar nicht mehr zu trennen, sondern mit anderweitig verwendbarer (LERP-) Logik zu filtern, fändest du nicht so toll?

Demirug
2003-06-21, 18:23:32
Original geschrieben von aths
dr,

den Ansatz, TMU- und ALU-Logik gar nicht mehr zu trennen, sondern mit anderweitig verwendbarer (LERP-) Logik zu filtern, fändest du nicht so toll?

Im Prinzip schon nur besteht eine TMU ja aus ein bischen mehr als nur ein paar linearen Blendeinheiten. Und diese ganze Funktionalität über die shader programmierbar zu machen wäre sicherlich eine schöne sache die mit PS 3.0 ja auch möglich ist. Aber der Performanceverlust ist derzeit noch zu hoch dafür. Aus diesem Grund müssen bis auf weiteres eben noch TMUS verbaut werden.

robbitop
2003-06-21, 19:12:11
mal Klartext Demi:
ein Pixelshader 3.0 wäre denkbar mit dem R3xx Design, ohne grosse Kompromisse und Performancedrops?

dann bliebe lediglich der Vertexshader ...wie sieht es hier aus? Komplettes Redesign oder Upgrade?

Demirug
2003-06-21, 19:32:23
Original geschrieben von robbitop
mal Klartext Demi:
ein Pixelshader 3.0 wäre denkbar mit dem R3xx Design, ohne grosse Kompromisse und Performancedrops?

Machbar ja in Verbindung mit dem F-Buffer. Da es aber bis zum heutigen Zeitpunkt keine unabhängigen Aussagen über die Performance des F-Buffers gibt kann man auch nicht sagen wie gross der Drop wäre. Der F-Buffer kostet auf jeden Fall Bandbreite. Was meinst du jetzt mit Kompromisse? Entweder man kann alles was gefordert wird oder eben nicht. Mit den lösen des Branch/Loop Problems ist es aber aleine nicht getan es müssen noch ein paar andere Sache auf vorderman gebracht werden.

dann bliebe lediglich der Vertexshader ...wie sieht es hier aus? Komplettes Redesign oder Upgrade?

lediglich ist gut. :D wenn das was ich über den R300 PS gehört habe stimmt dann können sie das Teil für VS 3.0 nicht mehr benutzen.

robbitop
2003-06-21, 19:44:23
das ist recht interessant somit wären PS bis 2.0 so wie immer und PS 3 machbar mit Performancedrop, wobei es der R3xx nun wirklich nicht an bandbreite mangelt.

Wie kopliziert oder langwierig wäre es einen VS 3.0 zu entwickeln???
sicherlich dauert das etwas, deiner Reaktion

doch in Bezug auf Loci dürfte die Frage erübrigt sein, da man den VS 3 aus dem ehem. R400 entnehmen könnte....somit ist ein PS/VS 3.0 Loci denkbar...doch was bleibt im Featureset dann noch für den R500? (dies ist leider OT da wir ja im Techforum sind)

Demirug
2003-06-21, 20:14:27
Original geschrieben von robbitop
das ist recht interessant somit wären PS bis 2.0 so wie immer und PS 3 machbar mit Performancedrop, wobei es der R3xx nun wirklich nicht an bandbreite mangelt.

Wie kopliziert oder langwierig wäre es einen VS 3.0 zu entwickeln???
sicherlich dauert das etwas, deiner Reaktion

doch in Bezug auf Loci dürfte die Frage erübrigt sein, da man den VS 3 aus dem ehem. R400 entnehmen könnte....somit ist ein PS/VS 3.0 Loci denkbar...doch was bleibt im Featureset dann noch für den R500? (dies ist leider OT da wir ja im Techforum sind)

Ja das wird jetzt alles sehr spekulativ und ich muss auch sagen das ich diese ganze Idee in knapp 4 Stunden nebenbei entwickelt habe und es da durchaus noch Fallen geben kann die ich übersehen habe.

Wenn das Featureset einer DX Version erschöpft ist muss MS eben ein neues DX herausbringen.

micki
2003-06-23, 10:12:38
@Demirug

hast du nicht mal das design der 3dLabs VPUs erklärt (das war in zusammenhang mit nem patent)? mit den vielen unabhängigen pixelpipes wodurch die immer einen cache mit pixeln hatten und jede pipe wenn sie fertig war sich den pixel nahm der als nächstes ansteht. (also falls ich das damals richtig verstand)

die VPUs sind ja nicht gerade langsam (so gf4200 niveau soweit ich weiß) und bieten die ganze flexibilität die man braucht, weil die anstatt der allesparallelkönnenden VectorUnits nur kleine flexible skalarUnits haben, davon aber dann 4mal soviel.

wenn das im pixelshader so laufen könnte, wäre das doch optimal...

obwohl ich nicht glaube dass jemand an jedem zweiten pixel beim conditional-jump etwas anderes berechnen möchte (bei spielen), weil es dann doch auflösungsabhängig zu optischen änderungen der bildwahrnehmung kommt (weil z.B. bei 640*480 wäre es wie rauschen und bei 1600*1200 wie dithering)


man müßte sich doch erstmal ein paar anwendungsbeispiele anschauen, in denen man wirklich jumps benötigt, um zu wissen wie sehr die pipes asynchron belastet würden, wenn das kaum der fall ist und man durch die eingesparrten transistoren wieder nen höcheren takt haben kann der die leerlaufzeiten kompensiert, dann wäre irgendwie alles beim alten. (wie bei texkill)



übrigens glaube ich dass du mit deinem fbuffer die pläne von ATI aufdeckst, denn wozu hätten die die technologie jetzt schon in den chips, wenn's nicht so wie bei NVidia wäre, quasi als vorkost auf die 3.0 chips. :D


MfG
micki

Demirug
2003-06-23, 11:04:06
Original geschrieben von micki
@Demirug

hast du nicht mal das design der 3dLabs VPUs erklärt (das war in zusammenhang mit nem patent)? mit den vielen unabhängigen pixelpipes wodurch die immer einen cache mit pixeln hatten und jede pipe wenn sie fertig war sich den pixel nahm der als nächstes ansteht. (also falls ich das damals richtig verstand)

die VPUs sind ja nicht gerade langsam (so gf4200 niveau soweit ich weiß) und bieten die ganze flexibilität die man braucht, weil die anstatt der allesparallelkönnenden VectorUnits nur kleine flexible skalarUnits haben, davon aber dann 4mal soviel.

wenn das im pixelshader so laufen könnte, wäre das doch optimal...

Ich habe mir die Patente nur bis zum Pixelbereich vorgenommen. Der Pixelbereich ist aber sehr undurchsichtig erklärt. Es wird zwar davon gesprochen das Branches möglich wäre aber es gibt keine Details. Zudem gibt es auch keine erklärung in wie weit man mit Werten welche aus einer Texture kommen noch weiter rechnen kann und ob dort Branches möglich sind. So wie man es den Patenten entnehmen kann gibt es bei 3dlabs zwei Arten von ALUs. Fliesspunkt ALUs für texturekoordinaten und IntegerALUs für Farbberechungen. Aber wie gesagt wird auf die Möglichkeiten kaum eingegangen.

Das mit den Skalar Units stimmt aber schon nur können die 16 Units des Vertexshaders im P10 alle immer nur den gleichen Befehl ausführen. Da ist also auch nichts mit Verzweigungen.

obwohl ich nicht glaube dass jemand an jedem zweiten pixel beim conditional-jump etwas anderes berechnen möchte (bei spielen), weil es dann doch auflösungsabhängig zu optischen änderungen der bildwahrnehmung kommt (weil z.B. bei 640*480 wäre es wie rauschen und bei 1600*1200 wie dithering)

man müßte sich doch erstmal ein paar anwendungsbeispiele anschauen, in denen man wirklich jumps benötigt, um zu wissen wie sehr die pipes asynchron belastet würden, wenn das kaum der fall ist und man durch die eingesparrten transistoren wieder nen höcheren takt haben kann der die leerlaufzeiten kompensiert, dann wäre irgendwie alles beim alten. (wie bei texkill)


Es wird sicherlich nicht die Regel sein das zwei nebeneinader liegende Pixel immer unterschiedliche Wege einschlagen. Aber wenn man prozedurale Texturen mit Kanten hat wird es vorkommen. und je mehr Branchs und Loops vorkommen desto höher die Wahrscheinlichkeit. Für die erste Rheie von 3.0 Hardware (ausnahme DR) könnte das aber durchaus ein gangbarer weg sein.

texkill? Alles was texkill macht ist ein flag setzten das der Pixel nicht in den Framebuffer darf. Beim R300 verursacht ein Texkill auch noch einen Phasenwechsel. Rechenleistung kann man da nicht wirklich sparen. Ich hätte aber gerne das texkill als Earlyout funktioniert.


übrigens glaube ich dass du mit deinem fbuffer die pläne von ATI aufdeckst, denn wozu hätten die die technologie jetzt schon in den chips, wenn's nicht so wie bei NVidia wäre, quasi als vorkost auf die 3.0 chips. :D


MfG
micki

Ich dachte immer der F-Buffer ist primär für OpenGL 2.0 da. Mir ging es eigentlich nur darum wie man eben mit dem was ATI im Moment hat PS 3.0 noch einigermassen effektiv implementieren könnte.

micki
2003-06-23, 11:19:57
aber der F-Buffer war ja nicht von anfang an auf der featureliste soweit ich weiß, erst seitdem NVidia mit ihren 1024 instruktionen protzten. und da ich nicht glaube dass ATI so schnell so ein feature in ein chipdesign einbringt, denk ich mir dass das schon als vorstufe für 3.0 drinne ist.
Deine beschreibung in wieweit das so sein könnte klingt für mich logisch. (Bzw. wie die den FBuffer nutzen könnten) *dirnichtsindenmundlegenwill*



an sich ist aber das beispiel dann von Zeckensack perfekt. wenn man performant mit möglichst wenig verlust eine mandelbrot menge berechnen kann, dann hat man einen guten pixelshader.

vielleicht ist das ja der grund, weshalb NVidia am anfang lieber DDR2 anstatt 256Bit benutzt hat, weil damit der lost minimiert wäre, wenn ein pixel total die rekursion braucht und 3nicht (jetzt sind es ja 7).


das mit der gleichen instruktion beim P10 wuste ich nicht, aber es sollte ja nicht unmöglich sein das ein wenig zu entkoppeln.


MfG
micki

Demirug
2003-06-23, 15:31:08
Original geschrieben von micki
aber der F-Buffer war ja nicht von anfang an auf der featureliste soweit ich weiß, erst seitdem NVidia mit ihren 1024 instruktionen protzten. und da ich nicht glaube dass ATI so schnell so ein feature in ein chipdesign einbringt, denk ich mir dass das schon als vorstufe für 3.0 drinne ist.
Deine beschreibung in wieweit das so sein könnte klingt für mich logisch. (Bzw. wie die den FBuffer nutzen könnten) *dirnichtsindenmundlegenwill*

Ja die überlegung hat was für sich. Sie haben das ganze ja recht schnell aus dem Hut gezaubert.

an sich ist aber das beispiel dann von Zeckensack perfekt. wenn man performant mit möglichst wenig verlust eine mandelbrot menge berechnen kann, dann hat man einen guten pixelshader.

Ja wobei noch extremer dürfte Raytracen im Pixelshader sein.

vielleicht ist das ja der grund, weshalb NVidia am anfang lieber DDR2 anstatt 256Bit benutzt hat, weil damit der lost minimiert wäre, wenn ein pixel total die rekursion braucht und 3nicht (jetzt sind es ja 7).

Glaube ich nicht. Ich denke es ging wirklich nur darum Platz auf dem PCB zu sparen.


das mit der gleichen instruktion beim P10 wuste ich nicht, aber es sollte ja nicht unmöglich sein das ein wenig zu entkoppeln.


MfG
micki

Ja möglich ist das sicher nur steigt dann eben auch der Transitorecout. Ich bin aber sowieso eher für Skalarrechner als für Vektorenrechner.

egdusp
2003-06-23, 18:45:18
Mal eine Frage an die Experten, welche Effekte benötigen PS und VS 3.0?

Bei den VS weiß ich, dass sie aus einer Textur samplen können, was z.B. für Matrox Displacement Mapping notwendig ist.

Aber bei den PS 3.0 habe ich keine Ahnung, welche besseren und sinnvollen Effekte möglich sind.

mfg
egdusp

Demirug
2003-06-23, 20:51:00
Im Prinzip (mal von der Shaderlänge abgesehen) kann man mit den 3.0 Shadern kaum etwas machen was mit PS 2.0 nicht auch möglich wäre.

Der Vorteil bei den 3.0 Shadern ist aber nun das man in einen PS mehr als einen Effekt packen kann und dann dynamisch pro Pixel entscheiden kann welcher nun benutzt wird.

So könnte man zum Beispiel folgendes tun:

Wir brauchen etwas Holz. Abhängig von der Entfernung zum Betrachter könnte man nun:

Das Holz genau berechnen. (Prozedurale Texture)
Das Holz und die Bumpmap aus einer Texturen sampeln
Nur noch das Holz samplen und die Bumpmap ignorieren weil sowieso zu weit weg.

Der Vorteil dabei ist das man nicht für Pixel die sowieso zu weit weg sind als das man den schönen Effekt noch sieht rechenleistung verschwendet.