[Grafikkarten-Theorie] Abschätzung der FPS auf Grund einer GPU-Architektur

Faust2011

HTTP 418 - I'm a teapot
Moderator
Registriert
Aug. 2011
Beiträge
12.884
Hallo Leute,

hat jemand für mich ein paar Links auf Seiten parat, die sich damit beschäftigen, wie man anhand einer GPU-Architektur abschätzen kann, wie viele 'frames per second' zu erwarten sind?

Ich weiß, dass das ein komplexes Thema ist und natürlich stark davon abhängt, welche Szene man überhaupt rendern muss. Ich stelle mir das so vor:

1) Eine GPU ist grob gegliedert in drei Bereiche
- Frontend (mit Tesselator, Rasterizer)
- Shader (hier finden die eigentlichen Kalkulationen statt und hängen die TMUs
- ROPs


2) Die Szene, die gerendert werden soll
Szene 1 (einfach): Mehrere tausend Polygone, ohne Texture, ohne Tesselation
Szene 2 (komplexer): Dieselbe Szene, jetzt mit Texturen
Szene 3: wie Szene 1, jedoch mit Einsatz von Tessellation
Szene 4: wie Szene 1, jedoch in der Darstellung Aktivierung von Antialiasing

Anhand der GPU-Architektur und der definierten Szene möchte ich nun abschätzen (es soll wirklich nur eine Schätzung sein), wie viele FPS generiert werden könne.

Ein Beispiel:
Die Radeon 5870 taktet mit 850 MHz und hat 320 5D-Shader. Damit kann sie 320 Vektoren (also ca. 100 Dreiecke) 850 Millionen mal pro Sekunde durch die Shader schicken. (Vorausgesetzt, weder das Frontend (Tesselator, Rasterizer, ...) noch die ROPs limitieren. Wie viele Shader-Durchläufe sind nun nötig, um ein Frame zu rendern? Vertex-Shader, & Fragment Shader -> 2 Durchläufe? Damit könnte man eine Szene mit 100 Dreiecken 425 Millionen mal pro Sekunde rendern? Hmm... nein, da muss doch ein Denkfehler sein.

Grüße
Faust
 
Ein Denkfehler liegt darin, dass du die GPU zu sehr simplifizierst. Es kostet Zeit, die Daten auf die Shader zu verteilen. Und die Bandbreite zwischen GPU-Speicher und GPU ist beschränkt. Und ein fertig berechnetes Frame besteht nicht mehr aus Dreiecken sondern aus Pixeln.

Indem du sagst "Vorausgesetzt, weder das Frontend noch die ROPs limitieren" machst du ja schon unrealistische Einschränkungen.
 
Zuletzt bearbeitet:
Das kannst Du so nicht vergleichen weil es auch immer auf die engine ankommt.

Mal als ganz krasses Beispiel: die GeForce hat glaub ich den T&L-Kram eingeführt, das hat damals bei nahezu allen verfügbaren Spielen erstmal null gebracht. Derzeit ist das aber Standard. Die effektive Rechenleistung solcher spezialisierter Strukturen ergibt sich also immer aus dem Anwendungsgebiet.
Bei CPUs ist das ähnlich, egal welche Erweiterung, seie s oldschool MMX, etwas neuer x64 oder AVX und Co, solange die software das nicht unterstützt, bringt es garnichts. Funktioniert es, kann die Rechenleistung teilweise um Potenzen ansteigen.

Und um Deinen Denkfehler weiterzuspinnen: das sind pipelines, da bringt es den FPS wenig wenn Du massiv Polygone durch die Gegend schubsen kannst aber dann die Texturierung hinterherhinkt. Du hast den Eindruck dass die shader die Rechenleistung erbringen, das ist aber so nicht richtig. Wenn das Frontend mies ist und die tesselation versagt, bringt Dir der Rest auch nicht mehr viel. Ich würde sogar eher sagen, wenn Du bei der tesselation einen Geniestreich hinlegst und die Objekte in für Deine pipeline passende Aufgaben aufbrichst, ist das der wichtigste Teil des Ganzen.
 
Hallo,

danke für Eure Antworten soweit. Ich möchte auf Grund Eures Inputs mein (vereinfachtes) Szenario ein bisschen ausbauen. Ausgangspunkt ist nun eine Renderpipeline. Die Szene, die gerendert werden soll, ist weiterhin sehr einfach: es sind ca. 100 Dreiecke. Es wird weder Tesselleation, noch Texturen, noch ein Art von Anti-Aliasing verwendet!

Welche Schritte werden nun auf der GPU durchlaufen?

1) Vertex-Shader: hier werden die Dreiecke einfach auf die 'Welt' gemappt:

void main()
{
gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
}

Wie teuer (Taktzyklen auf der GPU) ist die Operation?


2) Fragment-Shader: alle Punkte werden gleich coloriert:

gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);

Wie teuer (Taktzyklen auf der GPU) ist die Operation?

3) Rasterizer: rendert die Daten ins Video-RAM zur Darstellung.

Wie teuer (Taktzyklen auf der GPU) ist die Operation?

Ist die Pipeline (bzw. der Render-Prozess) damit vollständig? Fehlt noch eine Stufe in der Pipeline?

Noch eine Frage: kann hier überhaupt die Speicherbandbreite limitierend wirken? Bei so wenigen geometrischen Daten sollten doch die Daten komplett im L1-Cache der Shader liegen. Das müßte ich mal nachrechnen.

So, viel Text gechrieben, deshalb nochmals kurz die Fragen in der Übersicht:
1) Sind die beschriebenen Pipeline-Stufen vollständig, oder fehlt noch was?
2) Wie viele Taktzyklen vergehen in den einzelnen Stufen?

Danke und Grüße
Faust
 
Faust2011 schrieb:
Noch eine Frage: kann hier überhaupt die Speicherbandbreite limitierend wirken? Bei so wenigen geometrischen Daten sollten doch die Daten komplett im L1-Cache der Shader liegen. Das müßte ich mal nachrechnen.
Das fertige Bild landet nachher im Speicher, deshalb muss die Bandbreite berücksichtigt werden. Für deine Berechnungen musst du also auch die Auflösung und die Farbtiefe (um die Größe eines Pixels angeben zu können) des fertigen Bildes mit einbeziehen.

Du könntest es natürlich so weit reduzieren, dass du sagst, dass das fertige Bild einen Pixel groß ist und dieser entweder schwarz oder weiß (also 1-Bit groß) ist. Aber das wäre dann ziemlich realitätsfern und du willst ja schon einen gewissen Realitätsbezug haben.
 
Zuletzt bearbeitet:
Allgemein: Deine Pipeline ist falsch. Sie schaut in etwa so aus:

VertexDaten -> VertexShader -> Rasteriser -> Fragmentshader -> ROPs -> Framebuffer


Zum Vertexshader: Wenn man die Matrixen zu einer Matrix zusammenklammert und bereits auf der CPU multipliziert so benötigt man pro Vertex 16 FLOPS FMA. Wenn du das hochrechnest kannst du den theoretisch maximalen Vertexdurchsatz deiner GPU bei diesem Shader ausrechnen. Wie "lange" die Berechnung eines einzigen Vertexes dauert ist allerdings nur noch schwer zu sagen, da deine GPU vieeele Vertexe gleichzeitig berechnen kann (Titan hat 65 k Threads, welche je einen Vertexe oder ein Fragment zu einem Zeitpunkt berechnen können.) Da du deutlich weniger als die 65 k Vertexe hast ist diese Operation wohl durch die Dauer eines einzigen Vertexes limitiert und nicht durch den Durchsatz der Vertexe insgesamt.

Dann kommt der Rasterisierer. Dieser hat einen begrenzten Durchsatz an Dreiecken/s und an Pixeln/Fragmenten/s. Beides kann hier die Performance limitieren. Welches von beiden ist davon abhängig ob du große oder kleine Dreiecke zeichnest. Hier gilt wieder der Unterschied zwischen Durchsatz und Latenz zu beachten - gerade bei relativ kleinen Datenmengen.

Dein Fragmentshader ist ein einfaches WriteBack, und "kostet" keine Rechenoperation. Allerdings ist zu beachten, dass er ebenfalls Threads deiner GPU belegt, welche eventuell Rechenoperationen ausführen könnten. Dadurch wird dir das einfache Writeback auch *etwas* Performance kosten.

Nicht Beachtung hier fanden in diesem Post solche Sachen wie Cache/Speicher-Bandbreiten, Speicherlatenzen uvm. Solche Dinge werden sehr schnell so komplex, dass man auf Benchmarks eigentlich nicht verzichten kann. Im allgemeinen limitiert aber bei so einfachen Shadern immer der Rasterisierer.


Noch eine Frage: kann hier überhaupt die Speicherbandbreite limitierend wirken? Bei so wenigen geometrischen Daten sollten doch die Daten komplett im L1-Cache der Shader liegen. Das müßte ich mal nachrechnen.

Du verwendest hier nur Speicherzugriffe über die Rasterpipeline. In wie weit die den L1-Cache verwendet ist afaik bei NVIDIA und bei AMD nicht dokumentiert. Aber selbst wenn, so müssen die Daten ja zu Beginn des Aufrufs geladen und dann wieder zurückgeschrieben werden. Beides kostet Latenzen und Bandbreite,
 
Zuletzt bearbeitet:
Nai schrieb:
Dann kommt der Rasterisierer. Dieser hat einen begrenzten Durchsatz an Dreiecken/s und an Pixeln/Fragmenten/s. Beides kann hier die Performance limitieren. Welches von beiden ist davon abhängig ob du große oder kleine Dreiecke zeichnest. Hier gilt wieder der Unterschied zwischen Durchsatz und Latenz zu beachten - gerade bei relativ kleinen Datenmengen.


Danke für die Antwort. Bevor ich mein Beispiel der Pipeline umbaue, eine kurze Frage zum Rasterizer: ich habe gesehen, dass es bei modernen Grafikkarten sowohl einen Rasterizer im Frontend gibt, als auch die ROPs. In welcher Hardware ist denn der von Dir angesprochene Rasterizer angesiedelt?
 
Es gibt nur einen Rasterisierer der immer folgendes mehr oder weniger in dieser Reihenfolgen mit diversen weiteren Koordinatenumrechnungen macht:
Homogene Division, Clipping, Früher Tiefentest (Early Z), Attribut-Interpolation, Fragmenterstellung

ROPs kümmern sich um das was beim Zurückschreiben der Fragmente geschieht:
Sicherstellung der Fragmentreihenfolge bei Alpha Blending, Tiefentest und gegebenfalls das Update vom ZBuffer und das Zurückschreiben.

Wohin soll der Thread eigentlich führen?
 
Hallo Nai,

mir scheint, Du kennst Dich ganz gut aus in der GPU-Materie :)

Nai schrieb:
Wohin soll der Thread eigentlich führen?

Zu Deiner Frage: wie im Eingangspost geschrieben, möchte ich die Hardware moderner GPUs verstehen und daraus die Performance ableiten können. Naheliegend wäre es natürlich, einfach auf Benchmarks zu schauen. Ich möchte aber tiefer gehen und mir die Hardwareeinheiten anschauen.

Mir scheint, dass man jedoch nicht nur die Hardware verstehen muss, sondern auch die komplette Render-Pipeline (wie man sie z. B. in OpenGL programmiert) vor Augen haben muss.

So, noch eine Frage, die mich gerade umtreibt: geben die Chiphersteller eigentlich Aussagen zur Performance des Rasterizer in ihren GPUs ab? Wie schnell ist denn so ein Rasterizer bei aktuellen Grafikchips und wie viele davon hat eine GPU? Und in welcher Einheit wird das gemessen (müßte Pixel/sec. sein, oder? Schließlich ist das 'Ding' zwischen einem Vertex-Shader (--> Dreickspunkt) und einem Fragment-Shader (--> Pixel) angesiedelt)?
 
Performance des Rasterizers? Das wäre so als würde ein Automobilhersteller den Reibbeiwert seiner Kolben angeben. Natürlich hat der Hersteller Daten darüber. Aber zum einen kommst Du da in Bereiche welche schon langsam Richtung "Betriebsgeheimnis" tendieren, zum anderen warum sollte er das veröffentlichen? Der Kunde kann damit nichts anfangen und im Endeffekt treffen sie keine Aussage über die tatsächliche Leistungsfähigkeit.

Du hast eine KETTE an Funktionen und der Hersteller schaut wie er die einzelnen Glieder effizienter macht und passt die einzelnen Glieder in ihrer Leistungsfähigkeit an wie er es für sinnvoll erachtet. Diese Kette ist in einer realen Anwendung aber NIE zu 100% gleichmäßig ausgelastet. In Spiel A limitiert der Polygoncount, in Spiel B die Texturierung. Der Hersteller versucht einfach eine ausgewogene Mischung zu finden um die derzeit vorherrschende Technik gut darzustellen. Natürlich kann man über generelle Architekturoptimierungen etwas "generelle leistung" herausholen, aber die geringen Prozente Zuwachs pro Generationswechsel zeigen doch dass die wirklich großen Sprünge im Endeffekt durch zwei Dinge vollbracht werden: Transistoren und Hertz. Also, im Alltag durch einen shrink.

Diese "Kette" ist auch der Grund warum sich GPU-Architekturen von Spiel zu Spiel unterscheiden können und GPU-Hersteller X bei Engine Y, egal welches Spiel, idR immer als schnelelr anzusehen ist als Konkurrent Z - und bei einem anderen Spiel/ einer Engine kehrt sich das um.

Deswegen kannst Du auch die tesselation nicht rauslassen. Das ist kein "macht hüpsch" wie AA, das wäre so als würdest Du einen Motor betrachten und nimmst den Vergaser/ die Einspritzung raus.

P.S.: da er early Z anspricht... da geht es ja um mathematisch geniale Dinge von denen ich nichts verstehe, ähnlich wie die Sprungvorhersage. Wenn Du es schaffst einen Algorithmus zu finden um early Z früher in der Pipeline oder besonders effizient anzuwenden, kannst Du massive Rechenleistung herausholen. Early Z definiert quasi, was Du von Deiner position aus siehst (am Monitor) und verwirft den Rest. Was verworfen wird, fliegt aus der Pipeline, bleibt mehr Platz für andere Berechnungen.
Es gab Ende der 90er mal eine GPU welche nur in einer oder zwei Generationen produziert wurde und danach wieder in der Versenkung verschwand weil sie in der Praxis ein sehr inkonsistentes Verhalten an den Tag legte. Die war kleiner und eigentlich lowtech im Vergleich zu 3dfx, ATI und nVidia, aber hatte einen für die damalige Zeit sehr früh und sehr rigoros greifenden early Z-Test. In manchen Spielen gingen die FPS durch die Decke, in anderen durch den Boden.
Frag mich nicht mehr wie das hies, es war nicht der Parhelia. Irgendein Neueinsteiger damals :)
 
Mir scheint, aus einer GPU-Architektur auf die Performance zu schließen ist nur schwer möglich. Da sind einfach zu viele Einflussfaktoren mit drin: wie groß und komplex ist die zu rendernde Szene... welche Schritte der Grafik-Pipeline werden mit welchen Daten durchlaufen... liegen die Daten bereits im Cache oder müssen sie aus dem GrKaSpeicher geholt werden... usw. usf.

Umgekehrt wird leichter ein Schuh draus: man schaut sich Benchmarks an und schließt dann auf Veränderungen in der Hardware. Ein Beispiel dafür war die deutlich verbesserte Tessellation-Performance der Radeon HD 6000 gegenüber HD 5000.
 
Zurück
Oben