R900 Spekulationsthread

- Optimierungen in den Strukturen: wie sieht es denn mit 6D-Shadern aus? 6D läßt sich halbieren und dritteln im Gegensatz zu 5D...
Warum nicht 12D, das kann man halbieren, dritteln, vierteln und selchsteln... :]
Dann kann man eigentlich gleich 320D machen... oder eben 320 skalare Shader..
Damit wäen wir beim Nvidia-Muster.
Dass ATI 5D-Shader hat, ist bestimmt nicht aus spaß der Fall weil dem Ingineur die Zahl so gut gefiel...
d.h. wenn sich diese Zahl ändert dann muss das ebenfalls einen Grund haben.
Ich habe schon spekuliert ob die 5D von RGB + alphakanal + 1 zus. Komponente herrühren, was angesichts der tatsache dass normalerweise Pixel berechnet werden nachvollziehbar wäre.
Ob es jetzt sinnig ist daraus 6 zu machen wage ich zu bezweifeln.
Bringt aber auch nichts, da höchstens die anzahl der Stream-Prozessoren geändert wird, also der aufbau auf höherem Level, man reißt da nicht einfach die rechenwerke auseinander.. *noahnung*
Lassen wir uns überraschen was SI wirklich bringt... und wenn das nur dafür sorgt dass die evergreen-Preise weiter purzeln...
 
Ich habe schon spekuliert ob die 5D von RGB + alphakanal + 1 zus. Komponente herrühren, was angesichts der tatsache dass normalerweise Pixel berechnet werden nachvollziehbar wäre.
Da mußt Du nicht spekulieren, das ist offiziell so. Schon sehr viel früher, als man noch keine unified shader hatte sondern noch getrennte Vertex- und Pixelshader, hießen die Komponenten beim Vertexshader xyzw (Koordinaten + Gewicht [weight]) und die beim Pixelshader rgba (Farben + Transparenz [alpha]). Damals waren das aber sogar wirklich noch als vec4 (4D) bzw. vec3+1 (3D+1) zu bezeichnen, heute passen die Bezeichnungen bei dem VLIW-Krams von ATI nicht mehr.
Als dann die unified shader (alle Shader laufen auf den gleichen Einheiten) Architekturen kamen (R400/Xenos, R600), benannte man die einzelnen Slots einfach x, y, z, w wie bei den Vertexshadern (die kommen zuerst, Pixelshader logisch erst danach). Der fünfte Slot ist außer als normale ALU auch für die transzendenten Funktionen zuständig, weswegen der Slot t heißt.

Die Bezeichnungen sind aber heutzutage eher traditioneller Natur, da diese Zuordnung (außer t) sowieso nicht mehr in der Form wie früher gegeben ist. Aber daraus erklärt sich vielleicht auch, wieso man bei Grafik die Slots meist ziemlich gut voll bekommt. Ein float4 ist logischerweise ein ziemlich gebräuchlicher Datentyp, bei dem man immer gleich mit 4 Komponenten rechnet.
 
Zuletzt bearbeitet:
ok, danke für die aufklärung :D
Dann kämen sie ja eigentlic hdoch mit 4D aus, sofern die anderen alus evtl. aufgebohrt werden um auch trnaszendente funktionen rechnen zu können...!?
Wobei da dann trotzdem irgendwie 1 schritt fehlt...
 
ok, danke für die aufklärung :D
Dann kämen sie ja eigentlic hdoch mit 4D aus, sofern die anderen alus evtl. aufgebohrt werden um auch trnaszendente funktionen rechnen zu können...!?
Man kommt auch mit 1D-Shadern aus, siehe nvidia. Die Frage ist eigentlich eher, was ist effizienter ? ;)

Übrigens sind die ATI-Einheiten keine 4D oder 5D Shader. Das sind VLIW-Einheiten mit 4 oder 5 parallelen Slots. Der Unterschied ist, daß z.B. 4D (oder auch vec4 genannt) Einheiten mit SIMD arbeiten, also nur eine Instruktion für alle 4 Komponenten ausgeführt wird. Bei ATI kann aber in jedem Slot eine andere Anweisung ausgeführt werden. Das entspricht also VLIW, bei dem in eine recht große Instruktion (die ist im nativen Format 64Bit pro Slot + zwei 64 Bit Konstanten, also 7x64 Bit = 448 Bit = 56 Byte lang, wahrscheinlich gibt es irgendwo noch 8 Byte padding, das heißt nicht umsonst VLIW ;)) bis zu 5 explizit parallele Operationen gepackt werden können (ab Evergreen gehen mit Einschränkungen sogar abhängige). Dabei nutzt man den bei Grafikanwendungen im Normalfall recht hohen ILP aus, ist aber nicht so beschränkt, wie es reine SIMD- bzw. Vec-Einheiten wären.
Wobei da dann trotzdem irgendwie 1 schritt fehlt...
*noahnung*
Was für ein Schritt fehlt?
 
Zuletzt bearbeitet:
ok, danke für die aufklärung :D
Dann kämen sie ja eigentlic hdoch mit 4D aus, sofern die anderen alus evtl. aufgebohrt werden um auch trnaszendente funktionen rechnen zu können...!?
Wobei da dann trotzdem irgendwie 1 schritt fehlt...

Jetzt solltest du allerdings in Deckung gehen, denn Gipsel versucht seit einer Weile im 3DCenter den Windmühlen genau diese Bezeichnung auszutreiben. :P


Edit: zu spät
 
das mit dem Schritt war doof ausgedrückt, vergiss es...
Was ich mich frage ist...wenn die 5-fachen Shader 5 eigenständige, parallele instruktionen berechnen können, ist das doch äquivalent dazu, 5 skalare shader stattdessen zu nehmen...
wo ist da also der effizienzvorteil?
Wenn ich sowieso 5 einzelne instruktionen verarbeiten muss, ist es doch unerheblich ob das in 5 skalaren oder 1 5-Fach shader passiert...!? Oo
 
Wenn ich sowieso 5 einzelne instruktionen verarbeiten muss, ist es doch unerheblich ob das in 5 skalaren oder 1 5-Fach shader passiert...!? Oo
Naja ist halt einfacher für den Decoder / Scheduler, wenn statt 5 einzelner µOps eine dicke MacroOp durch die Pipelines rutscht.
Kannst Dir mal die Idee bei IA64 nachlesen, wenn Du magst, ist der gleiche Ansatz.

Problematisch wirds nur möglichst effiziente 5er Packs zu schnüren.
 
das mit dem Schritt war doof ausgedrückt, vergiss es...
Was ich mich frage ist...wenn die 5-fachen Shader 5 eigenständige, parallele instruktionen berechnen können, ist das doch äquivalent dazu, 5 skalare shader stattdessen zu nehmen...
wo ist da also der effizienzvorteil?
Wenn ich sowieso 5 einzelne instruktionen verarbeiten muss, ist es doch unerheblich ob das in 5 skalaren oder 1 5-Fach shader passiert...!? Oo
Nun, die Verwaltung der Einheiten ist viel einfacher. Da die ganze Parallelisierung (das Packen der Operationen in die VLIW-Bündel) vom Compiler gemacht wird, muß man erheblich weniger Einheiten ansteuern können. Das spart ganz erheblich Verwaltungsoverhead, der dann in mehr Einheiten investiert werden kann. Das ist mehr oder weniger das Geheimnis von ATIs doppelt so hoher Peakleistung auf weniger als zwei Dritteln der Die-Fläche im Vergleich zu GF100.

Ein Cypress hat im Prinzip nur 320 VLIW-Einheiten mit jeweils 5 Slots organisiert in 20 SIMDs zu je 16 Einheiten. Jeder SIMD-Block arbeitet über 4 Takte verteilt jeweils 64 "threads" (work items trifft es besser, 64 work items sind eine wavefront) ab und es wechseln sich dazu immer noch 2 Wavefronts alle 4 Takte ab. Summa summarum muß ein Cypress zu jedem Zeitpunkt nur 40 gleichzeitig laufende Wavefronts verwalten (die die ALUs benutzen, Speicherzugriffe passieren parallel).

Ein GF100 hat schon mal gleich 512 Einheiten (die zudem noch höher getaktet sind, also schwerer zu designen sind und eine deutlich längere Pipeline besitzen), gegliedert in 16 SMs (enstprechen in etwa ATIs SIMDs), aber mit jeweils 2 Schedulern (32 insgesamt). Jeder Scheduler muß mindestens 5-6 Warps (entsprechen ATIs Wavefronts) am Laufen halten, um die Ausführungslatenzen der ALUs zu verstecken (die sind recht hoch ~20 Takte, ATI steht bei 8 ), kommen SFU oder Speicherzugriffe ins Spiel, werden es sehr schnell mehr (da noch höhere Latenz, ATI nutzt da ein deutlich anderes System, um die zu verstecken). Das macht dann für einen Fermi schon mindestens 32*5=160 Warps, die verwaltet werden wollen. Bei realen Anwendungen sind es deutlich mehr. Zur Erinnerung, bei einem Cypress sind es immer exakt 40.

Jetzt die Preisfrage, wo gehen wohl mehr Transistoren für die Verwaltung drauf?
 
Edit:
Ok, nun ist der groschen gefallen... die 5er-Päckchen bei ATI sind eine einzelne instruktion... sozusagen...
zumidnest werden sie so verwaltet, d.h. man braucht nur ein fünftel der veraltung um den selben effekt zu erzielen, man verwaltete also 320 Recheneinheiten, die eben "fette" 5er-Instruktionspäckchen verarbeiten anstatt 512 Einheiten mit einzel-instruktionen versorgen zu müssen...
 
Zuletzt bearbeitet:
@GeOrgy:
Falls es nach Gipsels ausführlicher Antwort noch unklar sein sollte, der Versuch eines Vergleichs:
Stell Dir vor Du müßtest 12 Hühnereier einmal mit oder ohne Ei-Karton tragen ..

Was ist einfacher ? :)
 
Nun, Du mußt z.B. im Prinzip für 5 mal so viele Operationen checken, ob die Operanden da sind, die alle einzeln durch die Scheduler schicken usw. usf. Sowas läppert sich schon ganz ordentlich zusammen.

PS:
ATI muß sowas überhaupt nicht auf einzelner Instruktionsebene checken, da gibt es noch übergeordnete Verwaltungseinheiten, die sogenannten clauses, in denen noch viele VLIW-Anweisungen stecken. Das ist ziemlich ausgefuchst, um das so einfach wie möglich in Hardware zu gießen. Per Design sind für jede Instruktion in einer sogenannten ALU-Clause alle Operanden immer ohne Latenz verfügbar, genau wie die logische Latenz aller Instruktionen auch immer nur ein Takt beträgt (man kann also immer auf das Ergebnis des direkt davorstehenden Befehles zugreifen, ohne daß es zu einem Stall kommen könnte).
.
EDIT :
.

Stell Dir vor Du müßtest 12 Hühnereier einmal mit oder ohne Ei-Karton tragen ..

Was ist einfacher ? :)
Super Vergleich *great*
 
Okay... also kurz gesagt, wird die komplexität auf die Compiler-Seite verlagert um die HW einfacher hinzubekommen... Erinnert mich irgendwie an RISC... aber das Mit VLIW vs. RISC hatten wir ja schonmal ;)
Eigentlich der krasse gegensatz zu x86, wo die HW ja unheimlich komplexe spielchen mit Branch prediction, OoO-Execution etc. machen muss um erfolgreich zu sein, also wesentlich "intelligentere" HW erforderlich ist, weniger Brute Force...
 
Warum hat NVidia diesen verwaltungstechnischen aufwändigen Weg gewählt? Welche Vorteile versprechen sie sich davon? Die Nachteile kennen wir ja jetzt.
 
Das sie ihre Einheiten viel einfacher auslasten können. Das Problem bei AMD ist, das es ihnen bis jetzt nicht gelingt einen Shadercompiler zu bauen, der die Einheiten richtig ans Limit treibt. VLIW bietet viele Optimierungsmöglichkeiten, welche vom Treiber aber auch erst mal genutzt werden müssen.

NVidia hat dieses Problem nicht, da sie einfach die Instruktionen auf die Shader schmeißen können, wie sie angeflogen kommen und die Ausführung ist trotzdem noch effizient.

Allerdings sieht man ja an Fermi, das der Verwaltungsaufwand doch rießig wird und AMD selbst mit geringerer Auslastung ganz gut hinkommt, da sie einfach mehr Shader verbauen können.
 
Hier mal ein nettes Beispiel, wie man OpenCL-Code an die Architektur anpassen kann, um Leistung der Graka aus zu reizen:
http://developer.amd.com/documentation/articles/Pages/OpenCL-Optimization-Case-Study.aspx

Mal ein ganz einfaches Beispiel - man nimmt als Datentyp einmal float und einmal float4.

float fl11 = 1.0f;
float fl12 = 2.0f;
float fl13 = 3.0f;
float fl14 = 4.0f;

float fl21 = 1.0f;
float fl22 = 2.0f;
float fl23 = 3.0f;
float fl24 = 4.0f;

float fl31 = fl11 + fl21;
float fl32 = fl12 + fl22;
float fl33 = fl13 + fl23;
float fl34 = fl14 + fl24;

Oder:

float4 fl1 = { 1.0f, 2.0f, 3.0f, 4.0f };
float4 fl2 = { 1.0f, 2.0f, 3.0f, 4.0f };
float4 fl3 = fl1 + fl2;
 
Warum hat NVidia diesen verwaltungstechnischen aufwändigen Weg gewählt? Welche Vorteile versprechen sie sich davon? Die Nachteile kennen wir ja jetzt.
Der Vorteil ist einfachere Software / Treiber.
AMD muss quasi bei jedem Spiel den Treiber anpassen, dass die Pakete optimal geschnürt werden. Das dauert ...

Ist halt der Trade-Off, entweder einfachere hardware, dafürt kompliziertere Software, oder andersherum ...

@mocad_tom:
Hmm ... also den ersten Code sollte der ATi OpenCL Compiler eigentlich eigenständig ins zweite Format umbasteln können.
Aber was ich mich frage, was passiert auf ner nV Karte, wenn die ein float4 vorgesetzt bekommt ? Wie optimal ist das dann ?

ciao

Alex
 
Aber was ich mich frage, was passiert auf ner nV Karte, wenn die ein float4 vorgesetzt bekommt ? Wie optimal ist das dann ?

Anscheinend immer noch sehr gut. Spiele verwenden bei Vertex- und Pixelberechnungen fast nur float4 und die Auslastung der NV Shadereinheiten ist dabei sehr gut. Der Sheduler von NVidia scheint dort ganze Arbeit zu leisten, auch wenn dies natürlich mit extrem vielen Transistoren bezahlt wird.
 
@mocad_tom:
Hmm ... also den ersten Code sollte der ATi OpenCL Compiler eigentlich eigenständig ins zweite Format umbasteln können.
Da bin ich noch vorsichtig - sie gehen im Moment noch einen sehr spartanischen Weg ;)

Aber was ich mich frage, was passiert auf ner nV Karte, wenn die ein float4 vorgesetzt bekommt ? Wie optimal ist das dann ?

Da gehen ATI & nvidia zwei unterschiedliche Wege. ATI setzt vorraus, dass der Entwickler ein intelligentes Individuum ist und sich den Gegebenheiten anpasst, nvidia sagt ich mache meine Hardware einfacher programmierbar. ATI geht mehr diesen VLIW-Ansatz, den Itanium schon so ein bisschen gehen wollte. Bezeichnend finde ich ja auch diese SGEMM- und DGEMM-Werte von Prunedtree - wenn man sich hinsetzt und Hirnschmalz in die ATI-Architektur reininvestiert erhält man sehr ordentliche Ergebnisse.

ATI wird hier aber deutlich das (Treiber-)Entwickler-Büro aufstocken müssen. Wenn einige von den Fortran-Bibliotheken nur schon auf der GPU laufen würden.....
 
So wie es aussieht hat AMD damit das gleiche Problem wie Intel damals mit dem Itanium. Brachiale Rohleistung der Recheneinheiten durch VLIW, aber der erforderliche optimierende Compiler, der diese Einheiten auch auslasten kann fehlt immer noch.

Allerdings sieht man, das die Architektur von so einem Compiler extrem profitieren kann. Bei den freien Grafiktreibern für AMD Karten wurden rießige Performancesprünge erreicht, indem man einen JIT Compiler auf Basis von LLVM eingebaut hat. Schon alleine durch das ausnutzen von Preinstruktionen, welche es zu normalen Instruktionen "for free" dazu gibt, konnte man viel erreichen.

Da hat AMD im Bereich OpenCL anscheinend noch einiges nachzuholen.
 
Hier mal ein nettes Beispiel, wie man OpenCL-Code an die Architektur anpassen kann, um Leistung der Graka aus zu reizen:
http://developer.amd.com/documentation/articles/Pages/OpenCL-Optimization-Case-Study.aspx

Mal ein ganz einfaches Beispiel - man nimmt als Datentyp einmal float und einmal float4.
[..]
@mocad_tom:
Hmm ... also den ersten Code sollte der ATi OpenCL Compiler eigentlich eigenständig ins zweite Format umbasteln können.
Da hat Opteron vollkommen Recht. Das schafft der Compiler schon seit Jahren (diese Optimierung macht der Shadercompiler, der ATIs IL in die GPU-ISA übersetzt, der läuft auch über jeden DirectX- und OpenGL-Shader oder auch Brook- oder CAL-Kernel) spielend.
In dem von Dir (mocad) verlinkten Beispiel sind doch sogar Benchmarks drin, da sieht man, daß das auf GPUs fast gar nichts bringt. Der kleine Vorteil den man sieht, liegt ganz einfach daran, daß man ein Viertel der Speicherzugriffe spart und ATIs nativ immer 16 Byte mit einer Anweisung aus dem Speicher lesen können. Das dies der Flaschenhals in dem Beispiel ist, wird auch klar, wenn man sich mal ansieht, was passiert wenn Images (Werte werden über Textureinheiten gelesen) benutzt werden, die Performance verdoppelt sich glatt.

Wo es wichtig wird, ist wenn man OpenCL kernel auf CPUs ausführen will. Benutzt man die Vektordatentypen, dann wird das das 1:1 zu Vektor-SSE2/3-Befehle gemappt, wenn nicht, werden nur skalare SSE-Instruktionen benutzt. Im OpenCL-Compiler für CPUs steckt also kein ordentlicher Vektorisierer drin, wie z.B. in Intel-Compilern (die benötigen aber auch ewig fürs Kompilieren ;)), da ist Handarbeit angesagt. Aber bei GPUs ist es wirklich praktisch vollkommen egal für die Berechnungen (für Speicherzugriffe nicht), da kann man aber mit Vektordatentypen den Code übersichtlicher und kürzer gestalten.

Aber was ich mich frage, was passiert auf ner nV Karte, wenn die ein float4 vorgesetzt bekommt ? Wie optimal ist das dann ?
Meist auch besser als skalare Typen. Die Berechnungen der 4 Komponenten sind ja per Definition unabhängig, so daß das die Scheduler vor überhaupt keine Probleme stellt (ist manchmal sogar recht günstig um die Pipelines gefüllt zu halten, da nvidia GPUs im Gegensatz zu ATI doch recht lange Pipelines haben, ~20 Takte Latenz). Und der bereits erwähnte Vorteil mit den Speicherzugriffen trifft bei nvidia natürlich auch zu.
.
EDIT :
.

So wie es aussieht hat AMD damit das gleiche Problem wie Intel damals mit dem Itanium. Brachiale Rohleistung der Recheneinheiten durch VLIW, aber der erforderliche optimierende Compiler, der diese Einheiten auch auslasten kann fehlt immer noch.
Du, soo schlecht ist das bei ATI gar nicht. Sicherlich kann man wahrscheinlich fast überall noch ein paar bis vielleicht 20% Prozent rausholen, aber bis auf Spezialfälle sind keine riesigen Sprünge zu erwarten.

Der Vorteil den ATI hat, ist daß Grafikkrams normalerweise einen ziemlich hohen ILP hat, so daß man gar nicht so übermäßig viel investieren muß, um da anständig was zu extrahieren. Das unterscheidet sich doch ziemlich stark von CPUs (Itanium). Außerdem kann dort der Compiler ewig auf einem Stück Code rumkauen, um dann irgendwann mal was auszuspucken, Bei GPUs muß das just-in-time zur Laufzeit (beim ersten Aufruf des Shaders/Kernels) erfolgen. Da muß man notgedrungen Kompromisse machen.

Aber um mal eine Zahl zu nennen, bei B3D wurden irgendwann mal ein paar hundert Shader aus realen Spielen analysiert und man kam für die ATIs auf einen mittleren Füllgrad von etwa 3,5/5 Slots dort, das sind 70%. Selbst mit 70% Füllgrad hat man mehr arithmetische Leistung als nvidia GPUs beim Optimum von 100% Auslastung (den die auch längst nicht immer erreichen). Also an der Shaderleistung scheitert es im Normalfall bei ATI nicht.
 
Die Berechnungen der 4 Komponenten sind ja per Definition unabhängig

Ich weiß nicht, ob ich auf dem falschen Dampfer bin, hab auch gerade keine Zeit um da nochmal genauer nachzuforschen, aber was passiert zum Beispiel bei Swizzling? Haben die NVs 1D Shader eigene Register, oder arbeiten mehrere zusammen auf einem Vektorregister? Im ersten Fall könnte ich mir vorstellen, das es da schon Probleme geben könnte und swizzling ist ja keine soo seltene Operation.
 
Ich weiß nicht, ob ich auf dem falschen Dampfer bin, hab auch gerade keine Zeit um da nochmal genauer nachzuforschen, aber was passiert zum Beispiel bei Swizzling? Haben die NVs 1D Shader eigene Register, oder arbeiten mehrere zusammen auf einem Vektorregister? Im ersten Fall könnte ich mir vorstellen, das es da schon Probleme geben könnte und swizzling ist ja keine soo seltene Operation.
Nvidia arbeitet mit skalaren Registern (32bit), ATI mit 128bit (4x32bit) Registern, wobei aber bei ATI die Komponenten einzeln angesprochen werden können. Wenn die Registerfiles genügend Readports haben, dann ist Swizzling vollkommen umsonst (es wird ja einfach ein anderes Register als Eingangsoperand gelesen). Dies ist üblicherweise bei den meisten nvidia-Karten erfüllt. GF104 scheint allerdings deutlich zu wenig readports zu haben, um z.B. die 3 ALU-Blöcke in einem SM gleichzeitig mit madds (3 Quelloperanden) mit verschiedenen Operanden zu versorgen. GF104 kann pro SM offensichtlich nur 96 Operanden lesen (was bei 48 ALUs + SFUs + L/S doch sehr knapp ist, für 48 madds benötigt man 144 Operanden), wobei es noch zusätzliche Beschränkungen gibt, die beim Swizzling zum tragen kommen können.
 
So wie es aussieht hat AMD damit das gleiche Problem wie Intel damals mit dem Itanium. Brachiale Rohleistung der Recheneinheiten durch VLIW, aber der erforderliche optimierende Compiler, der diese Einheiten auch auslasten kann fehlt immer noch.
Der Unterschied ist nur, für AMD ist es momentan eher ein Luxusproblem, funktioniert ja auch so recht gut. Für Itanium war es lebensnotwendig, was bekanntlich im Endeffekt nicht zum Erfolg führte. Wobei Itanium sicherlich auch noch andere Probleme hatte.
 
Zurück
Oben Unten