2010-04-26 9 views
25

Ich war schockiert, als ich das gelesen (aus dem OpenGL wiki):Welche OpenGL-Funktionen sind nicht GPU-beschleunigt?

glTranslate, glRotate, glScale

Sind diese Hardware beschleunigt?

Nein, es gibt keine bekannten GPUs, die ausführen. Der Treiber berechnet die Matrix auf der CPU und lädt sie auf die GPU .

Alle anderen Matrixoperationen sind auch auf der CPU durchgeführt: glPushMatrix, glPopMatrix, glLoadIdentity, glFrustum, glOrtho.

Dies ist der Grund, warum diese Funktionen in GL 3.0 als veraltet gelten. Sie sollten Ihre eigene Math-Bibliothek haben, bauen Sie Ihre eigene Matrix, laden Sie Ihre Matrix auf den Shader.

Für eine sehr, sehr lange Zeit, die ich die meisten der OpenGL-Funktionen gedacht verwenden, um die GPU-Berechnung zu tun. Ich bin mir nicht sicher, ob das ein übliches Missverständnis ist, aber nach einer Weile des Nachdenkens macht das Sinn. Alte OpenGL-Funktionen (2.x und älter) sind aufgrund zu vieler Zustandsschalter wirklich nicht für reale Anwendungen geeignet.

Das macht mir klar, dass möglicherweise viele OpenGL-Funktionen die GPU überhaupt nicht verwenden.

Also, die Frage ist:

Welche OpenGL Funktionsaufrufe verwenden Sie nicht die GPU?

Ich glaube, die Antwort auf die obige Frage zu wissen würde mir helfen, ein besserer Programmierer mit OpenGL zu werden. Bitte teilen Sie einige Ihrer Einsichten.

Edit:

Ich weiß, diese Frage leicht zu Optimierungsstufe führt. Es ist gut, aber es ist nicht die Absicht dieser Frage.

Wenn jemand eine Reihe von GL-Funktionen auf einer bestimmten populären Implementierung (wie AshleysBrain vorgeschlagen, nVidia/ATI und möglicherweise OS-abhängig), die die GPU nicht verwenden, das ist, was ich bin!

Plausible Optimierungshilfen kommen später. Konzentrieren wir uns auf die Funktionen für dieses Thema.

Edit2:

In diesem Thema geht es nicht darum, wie Matrixtransformationen arbeiten. Dafür gibt es othertopics.

+7

Es gibt nichts zu schockieren. Sie rufen 'glTranslate' nicht für jeden Vertex oder jedes Fragment auf, und es ist sowieso nur eine Matrixmultiplikation, so dass es normalerweise keinen Leistungseinbruch gibt, wenn Sie es auf der CPU ausführen. – Thomas

+1

@Thomas: Sie sind völlig richtig. Aber am Anfang fällt es den Leuten schwer, über die Grafik-Rendering-Pipeline nachzudenken, und wo der Vertex-Shader mit 'glTranslate()' sitzt. Nach einer Weile wird es klarer, aber am Anfang dachte ich "Oh, das muss GPU-beschleunigt werden", daher die Frage. –

+0

Ich dachte, dass T & L für Transformation & Lighting steht, was durch die Grafikkarte beschleunigt wurde. –

Antwort

35

Junge, ist das ein großes Thema.

Zunächst beginne ich mit dem Offensichtlichen: Da Sie die Funktion (jede Funktion) von der CPU aufrufen, muss sie zumindest teilweise auf der CPU laufen. Die Frage ist also, wie viel Arbeit auf der CPU und wie viel auf der GPU erledigt wird.

Zweitens muss die CPU eine Kommandobeschreibung vorbereiten, damit die GPU einen Befehl ausführen kann. Die minimale Menge hier ist ein Befehlstoken, das beschreibt, was zu tun ist, sowie die Daten für die auszuführende Operation. Wie die CPU die GPU auslöst, um den Befehl auszuführen, ist auch etwas wichtig. Da die meiste Zeit dies teuer ist, macht die CPU es nicht oft, sondern bündelt Befehle in Befehlspuffern und sendet einfach einen ganzen Puffer für die GPU.

All dies zu sagen, dass die Weitergabe von Arbeit an die GPU keine freie Übung ist. Diese Kosten müssen gegen das Ausführen der Funktion auf der CPU (egal worüber wir reden) stehen.

Wenn Sie einen Schritt zurück machen, müssen Sie sich fragen, warum Sie überhaupt eine GPU benötigen. Tatsache ist, dass eine reine CPU-Implementierung die Aufgabe erfüllt (wie AshleysBrain erwähnt). Die Leistung der GPU kommt von seinem Design zu handhaben:

  • spezialisierte Aufgaben (Rasterung, Blending, Texturfilterung, Blitten, ...)
  • stark parallel Workloads (DeadMG wird in seiner Antwort darauf zeigt) , wenn eine CPU eher für die Arbeit mit single-threaded arbeitet.

Und das sind die Leitprinzipien zu folgen, um zu entscheiden, was in den Chip geht. Alles, was davon profitieren kann, sollte auf der GPU laufen. Alles andere sollte auf der CPU sein.

Es ist übrigens interessant. Einige Funktionen des GL (vor der Einstellung meist) sind nicht wirklich klar abgegrenzt. Display-Listen sind wahrscheinlich das beste Beispiel für eine solche Funktion. Jeder Treiber kann beliebig viel von dem Anzeigelistenstrom an die GPU (typischerweise in Form eines Befehlspuffers) für eine spätere Ausführung schieben, solange die Semantik der GL-Anzeigelisten beibehalten wird (und das ist etwas schwer von ) im Allgemeinen). Bei einigen Implementierungen wird nur eine begrenzte Teilmenge der Aufrufe in einer Anzeigeliste in ein berechnetes Format verschoben und der Rest des Befehlsstroms auf der CPU einfach wiedergegeben.

Die Auswahl ist eine andere, bei der unklar ist, ob es einen Wert für die Ausführung auf der GPU gibt.

Schließlich muss ich sagen, dass es im Allgemeinen wenig Korrelation zwischen den API-Aufrufe und der Menge der Arbeit auf der CPU oder der GPU gibt. Eine Zustandseinstellungs-API neigt dazu, nur eine Struktur irgendwo in den Treiberdaten zu modifizieren. Der Effekt ist nur sichtbar, wenn ein Draw oder ähnliches aufgerufen wird.

Ein Großteil der GL-API funktioniert so. An diesem Punkt ist die Frage, ob glEnable(GL_BLEND) auf der CPU oder GPU ausgeführt wird, ziemlich bedeutungslos. Es kommt darauf an, ob die Mischung auf der GPU stattfindet, wenn Draw aufgerufen wird. In diesem Sinne Most GL Eintrittspunkte werden überhaupt nicht beschleunigt.

Ich könnte auch ein bisschen auf Datentransfer erweitern, aber Danvil berührt es.

Ich werde mit dem kleinen "s/w Pfad" beenden. In der Vergangenheit musste der GL nach den Spezifikationen arbeiten, unabhängig davon, welche Hardware-Spezialfälle es waren.Das bedeutete, dass, wenn die h/w nicht eine bestimmte GL-Funktion behandelte, sie es emulieren oder vollständig in Software implementieren musste. Es gibt zahlreiche Fälle, aber eine, die eine Menge Leute getroffen hat, ist als GLSL auftauchte.

Da es keine praktische Möglichkeit gab, die Code-Größe eines GLSL-Shaders zu schätzen, wurde entschieden, dass der GL eine beliebige Shader-Länge als gültig annehmen sollte. Die Implikation war ziemlich klar: Entweder implementiere ich h/w, das Shader mit beliebiger Länge - die zu dieser Zeit nicht realistisch waren - implementiere oder eine s/w Shader-Emulation implementiere (oder, wie einige Hersteller es wünschten, einfach nicht konform zu sein). Also, wenn Sie diese Bedingung auf einen Fragment-Shader ausgelöst haben, war die Wahrscheinlichkeit, dass die ganze Ihres GL auf der CPU ausgeführt wurde, auch wenn Sie eine GPU-Standort Leerlauf hatte, zumindest für diese zeichnen.

+2

Ich muss sagen, das * ist * eine lange Post. Es hat auch viel Geschichte, sehr schön. Ich habe es sehr genossen, es zu lesen. Bisher habe ich festgestellt, dass es keine definitive Liste gibt, aber eher eine allgemeine Richtlinie und Verständnis ja? Danke an alle. Ich werde diese Antwort akzeptieren und über das nächste Unmögliche nachdenken. –

7

Die Frage sollte vielleicht sein "Welche Funktionen essen eine unerwartet hohe Menge an CPU-Zeit?"

Einen Matrixstack für Projektion und View zu behalten, ist kein Ding, das die GPU besser behandeln könnte als eine CPU (im Gegenteil ...).Ein anderes Beispiel wäre die Shader-Kompilierung. Warum sollte das auf der GPU laufen? Es gibt einen Parser, einen Compiler, ..., die nur normale CPU-Programme wie der C++ - Compiler sind.

Potenziell "gefährliche" Funktionsaufrufe sind zum Beispiel glReadPixels, weil Daten vom Host- (= CPU-) Speicher zum Geräte- (= GPU-) Speicher über den begrenzten Bus kopiert werden können. In dieser Kategorie sind auch Funktionen wie glTexImage_D oder glBufferData.

Im Allgemeinen, wenn Sie wissen möchten, wie viel CPU-Zeit ein OpenGL-Anruf isst, versuchen Sie, seine Funktionalität zu verstehen. Und Vorsicht vor allen Funktionen, die Daten von Host zu Gerät und zurück kopieren!

+0

Danke, Danvil. Sie haben einen guten Kandidatenschlüssel ausgewählt, um herauszufinden, welche Funktionen CPU-Zeit verbrauchen. Und Speicherbus auch. +1. –

2

Es gibt Software gerenderten Implementierungen von OpenGL, so ist es möglich, dass keine OpenGL-Funktionen auf der GPU ausgeführt werden. Es gibt auch Hardware, die bestimmte Render-Zustände in der Hardware nicht unterstützt. Wenn Sie also einen bestimmten Zustand einstellen, wechseln Sie zum Software-Rendering, und wieder wird nichts auf der GPU laufen (obwohl es dort einen gibt). Ich denke also nicht, dass es eine klare Unterscheidung zwischen "GPU-beschleunigten Funktionen" und "nicht GPU-beschleunigten Funktionen" gibt.

Um auf der sicheren Seite zu bleiben, halten Sie die Dinge so einfach wie möglich. Die einfache Rendering-mit-Vertices und grundlegende Funktionen wie Z-Pufferung sind am wahrscheinlichsten hardwarebeschleunigt, also wenn Sie mit dem minimalen Zustand ändern können bleiben, werden Sie am ehesten Hardware-Beschleunigung beibehalten. Dies ist auch der Weg, um die Leistung des hardwarebeschleunigten Renderings zu maximieren - Grafikkarten bleiben gerne in einem Zustand und knacken einfach eine Reihe von Vertices.

+0

@Ashleys, habe ich die großen verschiedenen Implementierungen von OpenGL, und wo diese Zeile für diese Frage zu zeichnen. Ich denke, ich bin hier hinter einer Mehrheitsentscheidung. Danke für den Tipp, die Dinge einfach zu halten! –

+2

Vielleicht könnten Sie die Frage nach ATI/nVidia/Intel (Schaudern) Karten oder anderen führenden Herstellern formulieren, da ich denke, dass das der wahre Fall ist, in dem es auf Beschleunigung ankommt. – AshleysBrain

+1

könnte ich. Aber ich denke, dass diese Marken populär genug sind, um eine solche Klärung nicht zu rechtfertigen, hoffe ich? –

4

glTranslate, glRotate und glScale ändern die aktuelle aktive Transformationsmatrix. Dies ist natürlich eine CPU-Operation. Die Modellansicht und Projektionsmatrizen beschreiben nur, wie die GPU Vertices transformieren soll, wenn sie einen Renderbefehl ausgeben.

Also z.B. Mit dem Aufruf von glTranslate wird noch gar nichts übersetzt. Vor dem Rendern werden die aktuellen Projektions- und Modellansichtsmatrizen multipliziert (MVP = Projektion * Modellansicht), dann wird diese einzelne Matrix auf die GPU kopiert und dann führt die GPU die Matrix * -Vertex Multiplikationen ("T & L") für jeden Eckpunkt durch. Also die Übersetzung/Skalierung/Projektion der Scheitelpunkte ist erfolgt durch die GPU.

Auch sollten Sie sich über die Leistung keine Sorgen machen, wenn Sie diese Funktionen nicht irgendwo in einer inneren Schleife verwenden. glTranslate liefert drei Ergänzungen. glScale und glRotate sind etwas komplexer.

Mein Rat ist, dass Sie etwas mehr über lineare Algebra lernen sollten. Dies ist wichtig für die Arbeit mit 3D-APIs.

+0

Übersetzung, Rotation und Skalierung können mit Matrixoperationen durchgeführt werden und können sehr schnell von der Hardware ausgeführt werden. Sie sind nicht Teil der Pipeline, sondern ändern nur eine Matrix in der Pipeline, daher ist es sinnvoll, sie in der CPU zu belassen. Aber dann warum diese Funktionen in die OpenGL-API? Ich kann die Quelle der Verwirrung sehen. – phkahler

+0

Geschichte. Ich denke, das hat etwas mit dem Client/Server-Modell und dem Matrix-Stack, den der Treiber zur Verfügung stellt, zu tun. D3D ist in diesem Sinne sauberer, weil es diese Funktionen in D3DX setzt. –

+0

Danke, Axel, um zu klären, wo die Matrizen auf die GPU hochgeladen werden. Mir ist bewusst, wie diese Matrizen funktionieren und wie sie mathematisch funktionieren. Wie ich in dem Thema bearbeitet habe, bin ich nicht besorgt über die Geschwindigkeit in diesem Thema. || Wissen Sie übrigens, wie Sie diese MVP-Matrix zum Rendern mit OpenGL 3.x auf die GPU "kopieren" können? Ich kenne einen Weg - Vertex Shader - aber gibt es einen bevorzugten Weg? || (Mein Upvote ist begrenzt, wird +1, wenn ich kann.) –

7

Wenn eine Operation per-etwas ist, wird es normalerweise auf der GPU auftreten. Ein Beispiel ist die tatsächliche Transformation - dies wird einmal pro Vertex durchgeführt. Auf der anderen Seite, wenn es nur einmal pro große Operation auftritt, wird es auf der CPU sein - wie zum Beispiel das Erstellen der Transformationsmatrix, die nur einmal für jedes Mal, wenn sich der Zustand des Objekts ändert, oder einmal pro Frame durchgeführt wird.

Das ist nur eine allgemeine Antwort und einige Funktionalität wird anders herum auftreten - und auch abhängig von der Implementierung. In der Regel sollte es Ihnen, dem Programmierer, aber egal sein. Solange Sie dem GPU genügend Zeit lassen, um die Arbeit zu erledigen, während Sie das Spiel sim oder was auch immer machen, oder ein solides Threading-Modell haben, sollten Sie sich darüber nicht so viele Gedanken machen müssen.

@Sending Daten an GPU: Soweit ich weiß (nur Direct3D verwendet) ist alles in-Shader, das ist, wofür Shader sind.

+0

@DeadMG: Ihre Antwort war meine andere Wahl, nur zur Info. Kurz und kurz. –

Verwandte Themen