2010-07-13 10 views
14

Dies wurde wahrscheinlich gefragt, immer und immer wieder, aber ich konnte nichts Brauchbares finden so ist es hier wieder geht ...Tuning OpenGL-Performance für Geometrie Durchsatz

In meiner Anwendung brauche ich eine ziemlich große Masche zu machen (a ein paar Millionen Dreiecke oder mehr) und ich habe einige Probleme damit, brauchbare Bildraten zu bekommen. Die CPU ist ziemlich leer, also bin ich definitiv GPU-gebunden. Das Ändern der Auflösung wirkt sich nicht auf die Leistung aus und ist daher nicht fragment- oder rastergebunden.

Das Netz ist dynamisch (aber lokal statisch), so dass ich das Ganze nicht in der Videokarte speichern und mit einem Anruf rendern kann. Aus anwendungsspezifischen Gründen werden die Daten als Octree mit Voxeln in den Blättern gespeichert, mit Mitteln, die ich grundsätzlich kostenlos kupieren lasse. Die Vertex-Daten bestehen aus Koordinaten, Normalen und Farben - es werden keine Texturen oder Shader verwendet.

Mein erster Ansatz war, nur alles aus dem Speicher mit einem großen STREAM_DRAW VBO zu rendern, was sich als zu langsam herausstellte. Mein erster Gedanke war, dass ich den Bus vielleicht überforderte (~ 150 MiB pro Frame), also implementierte ich ein Caching-Schema, das Geometrie speichert, die kürzlich verwendet wurde, um das Objekt in statischen VBOs auf der Grafikkarte zu rendern 100 KiB zu ein paar MiB Daten (mehr pro VBO zu speichern gibt mehr Cache-Thrashing, also gibt es hier einen Kompromiss). Das Bild unten ist ein Beispiel dafür, wie die Daten aussehen, wobei alles, was rot gefärbt ist, aus zwischengespeicherten VBOs gezogen wird.

Example of the rendered data http://gimaker.users.sourceforge.net/0010.png

Wie die Zahlen unten zeigen, ich habe nicht eine spektakuläre Leistungssteigerung sehen, wenn Sie den Cache verwenden. Für ein vollständig statisches Netz von etwa 1 Million Dreiecken ich die folgenden Bildwiederholraten erhalten:

  • Ohne Caching: 1,95 Hz
  • Caching unter Verwendung von Vertex Arrays: 2,0 Hz (> 75% des Netzes ist gecached)
  • Caching mit STATIC_DRAW VBOs: 2,4 Hz

Also meine Frage ist, wie kann ich das beschleunigen? Ie .:

  • Was ist das empfohlene Vertex-Format, um anständige Leistung zu erhalten? Ich verwende Interleaved-Speicher mit Positionen und Normalen wie GL_FLOAT und GL_UNSIGNED_BYTE für Farben, mit einem Füll-Byte, um 4-Byte-Ausrichtung zu erhalten (28 Bytes/Eckpunkt insgesamt).
  • Ob die Verwendung der gleichen Puffer für Normalen für alle meine Boxen könnte helfen (alle Boxen sind Achse ausgerichtet, so dass ich einen normalen Puffer die Größe des größten Cache-Eintrag zuweisen und für sie alle verwenden).
  • Woher weiß ich, welcher Teil der Pipeline der Flaschenhals ist? Ich habe nicht eine spektakuläre Grafikkarte (Intel GM965 mit Open-Source-Linux-Treiber), so ist es möglich, dass ich seine Grenze erreicht. Wie viel Durchsatz kann ich von einer typischen Hardware (2-3 Jahre alte integrierte Grafik, moderne integrierte Grafik, moderne diskrete Grafik) erwarten?
  • Alle anderen Tipps, wie Sie dies angehen würde, Fallen etc.

Ich bin nicht daran interessiert, Antworten darauf hindeutet, LOD (ich dies bereits getestet), herstellerspezifische Tipps oder mit OpenGL-Funktionen von etwas später als 1,5.

+0

Besteht Ihre Primitive nur in Achsen-ausgerichteten Boxen? – Stringer

+0

@Stringer Bell: Ja (aber nicht unbedingt mit den Weltachsen ausgerichtet). – Staffan

+1

Ich bin mir nicht sicher, aber ich denke, Sie haben das Limit der Grafikkarte erreicht. Ich habe ein bisschen gegoogelt und es scheint, dass Intel GM965 eine ziemlich niedrige Leistung hat, besonders für Spiele. (Ihr ist kein Spiel, scheint aber ziemlich "schwer" zu rendern). Nvidia hat eine Liste, wie viele Dreiecke ihre Karten wiedergeben können/Sekunde - vielleicht kannst du deine Karte mit dieser Liste kategorisieren, um das "theoretische" Limit herauszufinden. – InsertNickHere

Antwort

5

Du bist wahrscheinlich nicht diese Antwort werde gerne ....

Ich habe Ihr Problem gefunden: Intel GM965 mit Open-Source-Linux-Treiber

Während meiner jetzigen Tätigkeit nicht trifft Ihr Volumen Daten, wir haben mehrere Millionen Eckpunkte in VBO gerendert und Intel Grafikhardware/Treiber haben sich als nutzlos erwiesen. Holen Sie sich eine NVidia-Karte (und kommen Sie mit dem Binär-Treiber, es funktioniert einfach) und Sie werden alle eingestellt werden. Muss nicht einmal aktuelle Generation sein, obwohl ein Top-End-Quadro (wenn die Arbeit zahlt) oder Top-End-GTX-400-Serie (wenn Sie zahlen oder nur versuchen, einige Dollars bei der Arbeit zu speichern) sollte gut mit den neuesten Fahrer. Sie könnten auch versuchen, eine Maschine mit dieser Hardware zu finden, an der Sie testen können, wenn das Upgrade Ihrer Maschine keine Option ist.

+0

Sieht aus, als hättest du recht. Ich habe an einer Maschine mit besserer Grafik getestet, nicht an einer Quadro, aber trotzdem besser, und habe 15 Hz mit Caching und die Hälfte ohne. Es ist eher eine Unannehmlichkeit als ein Problem, da ich nur der Entwickler bin und nicht (momentan) der Hauptnutzer davon bin. – Staffan

+0

@Staffan: es bedeutet nicht, dass Sie Ihre GMA 965 für mich maximal haben. Vielleicht machst du nur etwas Schlechtes für Auftritte. Ehrlich gesagt würde ich in Betracht ziehen, Intel Media Accelerator Profiler auszuprobieren (wenn Ihre Anwendung natürlich portabel ist). Vergiss nicht, dass GMA Kachel-basierte Renderer sind. – Stringer

+0

@Stringer Bell: Es scheint, dass es wirklich die Grafikkarte/Treiber ist, die das Limit setzen. Nach einigem Tuning meines Caching-Mechanismus bekomme ich ~ 28 Millionen Dreiecke/s auf einer GeForce 3 Ti200, es gibt keine offiziellen Angaben darüber, wie viele Dreiecke es schieben kann, aber es sieht so aus, als könnte es ziemlich nahe am Limit liegen. – Staffan

0

würde ich eine Performance Profiler zuerst (wie gDEBugger), so dass Sie herausfinden können, wenn Sie Vertex, ein Fragment oder Bus begrenzt sind, usw.Es ist schwer zu erraten, welche Optimierungen in einem solchen Fall durchgeführt werden sollen (Intel + Open-Source-Treiber).

Haben Sie auch den VA-Modus getestet? Verwenden Sie glDrawElements? glDrawArrays? Ist der Daten-Vertex-Cache freundlich (Pre- und Post-Transformation)?

+0

Bell: Ich würde einen OpenGL Profiler verwenden, wenn es eine Open Source (oder freie) für Linux gibt (siehe [meine andere Frage]) (http://stackoverflow.com/questions/3235864/open-source-opengl-profiler- für-Linux)). Die Open-Source-Treiber sind die von Intel entwickelten offiziellen Treiber, aber das wissen Sie vermutlich schon. Ich verwende glDrawArrays, da ich keine Daten zwischen Scheitelpunkten teilen kann (alle Scheitelpunkte haben unterschiedliche Normalen oder Positionen). Was ist der VA-Modus? Die Daten sind Cache-freundliche AFAICT, d. H. Verschachtelter Speicher (nicht sicher, wie Transformationen das beeinflussen würden). – Staffan

+0

Ich habe versucht, gDEBugger trotz Closed Source, und es funktioniert nicht für mich (gibt mir einen indirekten Kontext und verursacht dann eine SIGSEGV). – Staffan

+0

VA-Modus ist einfach alte 1.1 Vertex-Arrays. Post-Transformations-Caches werden nur verwendet, wenn Sie über Indizes verfügen (siehe http://www.opengl.org/wiki/Post_Transform_Cache). Verwenden Sie GL_QUAD oder GL_TRIANGLES zum Rendern Ihrer Boxen? – Stringer

0

Ich weiß nicht über Ihre "Mesh", aber es scheint, dass sie alle Würfel sind. Wenn es Ihnen möglich ist, können Sie einen Union Cube in eine Anzeigeliste rendern und eine skalierte Version dieser Anzeigeliste rendern. Dies führt oft zu einer 10-fachen Beschleunigung, da der Bus nicht mit Vertex-Daten oder dem erschöpften Videospeicher gepumpt wird.

Natürlich hängt das von Ihrer Fähigkeit ab, die Daten zu ändern. Es könnte nicht der Fall sein, wenn es wirklich nicht auf dem Bild ist.

+0

Sie sind alle Quader, ja. Wie ich im OP beschrieben habe, verwende ich einen Cache mit VBOs, um den Bus nicht zu überlasten - keine glVertex3() - Aufrufe waren an der Erzeugung des obigen Bildes beteiligt. – Staffan

+0

Aber VBO! = Display List ... Der Unterschied ist, dass VBO immer noch eine große ARRAY verwendet, auch wenn es im Videospeicher ist. In den meisten Fällen für Setups wie diese bekomme ich am meisten für einen Dollar, der 10000 x einen DL nennt, der 10000 Würfel in einem Eckpunktarray nennt. – rioki