Ich arbeite derzeit an einem OpenGl-Programm, dessen Leistung ich verbessern möchte. Die Leistung ist in Ordnung, aber bei leistungsstarken dedizierten GPUs nicht ideal, bei integrierten Grafiken (<10 fps) jedoch miserabel. In einem normalen Programm (CPU-basiert, kein OpenGl oder eine andere GPU-API) würde ich einen Profiler (möglicherweise den in CLion integrierten) für das Programm ausführen, sehen, wo die meiste Zeit verbracht wird, und dann an einem besseren Algorithmus arbeiten für diese Bereiche oder finden Sie einen Weg, um den Betrag zu reduzieren, den dieser Bereich genannt wird.
Die Verwendung dieser Technik in meinem OpenGl-Programm zeigt, dass der größte Teil der Zeit des Programms (~ 86%) in seinem Hauptthread (dem, den ich optimieren möchte) in der .so-Datei des OpenGl-Treibers verbracht wird. Darüber hinaus ist die CPU-Auslastung des Programms während der Ausführung sehr gering, die GPU-Auslastung liegt jedoch zwischen 95% und 100%. Zusammengenommen sagen mir diese Informationen, dass der Engpass in der GPU liegt, daher sollte ich dort optimieren.
Hier tritt ein Problem auf. Meine normale Technik, einen Profiler als Leitfaden für meine Optimierungen zu verwenden, funktioniert jedoch nicht ohne den spezifischen GPU-Profiler. Aus diesem Grund habe ich einige Nachforschungen angestellt, um einen Profiler zu finden, der mir sagt, wo die GPU-Verarbeitungszeit verbracht wird. Ich konnte nichts finden, was aus der Ferne verwendet werden kann. Alles war entweder nur für Windows (ich verwende ausschließlich Linux und mein Programm ist noch nicht auf Windows portiert - und wird es auch nicht sein, bis es viel weiter fortgeschritten ist), nicht mehr aktualisiert und / oder kostet weit mehr als das Budget für Dieses Projekt ist.
Daher frage ich: Wie kann ich die Leistung meines Programms optimieren, wenn der entsprechende Profiler nicht vorhanden ist? Ich habe versucht zu erraten, wo die Probleme liegen, und daraus optimiert, aber es machte überhaupt keinen Unterschied, obwohl ich feststellen konnte, dass meine Optimierungen (Kegelstumpf-Keulung) zu weniger Arbeit für die GPU um etwa die Hälfte führten. Eine gute Antwort gibt eine Profiling-Technik an, die für Opengl unter Linux gilt, oder eine Technik, die ohne Profiler funktioniert.
quelle
Antworten:
Indem Sie Ihren Code selbst profilieren. Das Auffinden von GPU-Engpässen ist nicht besonders schwierig.
Angenommen, Sie haben eine minderwertige Version von OpenGL ( Timer-Abfragen sind nicht verfügbar), dann tun Sie das, was die Leute seit Jahren tun: Ändern Sie Dinge und sehen Sie, wie es funktioniert.
Es gibt drei grundlegende Speicherorte für Engpässe beim Rendern: CPU (dh ineffizientes Senden von Daten), Vertex T & L und Verarbeitung pro Fragment. Um festzustellen, welcher Engpass vorliegt, müssen Sie lediglich die Auswirkungen auf die Leistung erkennen, wenn Sie etwas ändern.
Wenn Sie beispielsweise feststellen möchten, ob die Verarbeitung pro Fragment ein Engpass ist, reduzieren Sie die Anzahl der generierten Fragmente (dh die Auflösung des Bildschirms). Wenn sich die Leistung in Bezug auf die Anzahl der Pixel in der Bildschirmauflösung linear verbessert, war dies Ihr Engpass.
Wenn Sie wissen möchten, ob Ihre Scheitelpunktverarbeitung der Engpass ist, rendern Sie dasselbe Objekt mehrmals (nacheinander). Angenommen, Sie haben einen Tiefen-Test aktiv und mischen nicht, sollten die Fragmente aus den nachfolgenden Renderings vor dem Aufrufen des Fragment-Shaders ausgesondert werden. Wenn also die Leistung durch wiederholtes Rendern aller Objekte linear abnimmt, liegt ein Engpass bei der Scheitelpunktverarbeitung vor.
Und wenn keiner von beiden der Engpass ist, dann ist die CPU durch den Prozess der Beseitigung das Problem.
Wenn Sie Zugriff auf Timer-Abfragen haben, können Sie GPU-Vorgänge direkt zeitlich festlegen. Sie können bestimmte Phasen nicht zeitlich festlegen, aber Sie können die Zeit bestimmen, die GPU-Befehle benötigen, um ausgeführt zu werden. Sie können auch die Latenz zwischen dem Abschluss des GPU-Befehls und dem Ende des Sendens dieser Befehle durch den CPU-Thread ermitteln. Insgesamt sollten Sie anhand dieser Informationen feststellen, wie lange es dauert, bis die GPU Daten verarbeitet, verglichen mit der CPU, die sie sendet.
quelle