Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

07.06.2015, 00:46

OpenGL calls optimieren.

Hallo! :)

Kurz: Ich benutze OpenGL derzeit um Optimierungsprobleme auf Bildern zu lösen..... recht viel genauer will ich dazu nicht ins detail gehen. :ninja:
Jedenfalls scheine ich derzeit bezüglich performance einen ziemlichen CPU Flaschenhals zu erliegen. Das Problem ist nämlich, dass ich sehr oft zwischen Texturen als Textur und Texturen gebunden an FBOs hin und her wechseln muss. Und eben auch, nach jedem Wechsel einen draw call brauche.

Meiner Beobachtung nach ändert ein Wechseln des Texturformats von z.b. 16bit Float auf 32Bit Float nichts an der Performance.
->GPU Speicherbandbreite reicht aus!? (lieg ich in der Annahme richtig?)
Bevor ich vergesse: ich programmiere auf OS X (Macbook mit AMD Radeon HD6750M) und linux intel HD 4000 mit mesa driver. Der Code läuft nämlich auf dem Laptop mit Mesa Treiber schneller als am Mac obwohl die Grafikkarte um einiges langsamer sein sollte.
-> die GPU selber scheint nicht ausgereizt zu werden!?
Meine Vermutung ist einfach, dass die Treiber von Apple sehr viel mehr Overhead erzeugen als die Open source Mesa Treiber.
Um euch ein Bild von dem ganzen zu geben hab ich ein paar OpenGL calls mitgeschnitten (es ist ein interaktives Verfahren und benötigt unglaublich viele Schritte): :dash:


Ich hoffe es finden sich ein paar OpenGL Gurus, die mir da helfen können. Hauptsächlich würde ich gerne wissen wieso glDrawArrays immer zwischen 5 und 50us benötigt wenn der glFinish Befehl sowieso 42ms benötigt....... da mit glDrawAarrays noch keine Pakete mit Befehlen an die Grafikkarte übermittelt werden (zumindest nicht zwangsweise) wüsste ich gerne was bei glDrawArrays so lange dauert. Die Abarbeitung der Befehle auf der Grafikkarte wird doch bei glFinish (Anhang) abgewartet.

Edit: Wie bekomm ich die Bilder in diesem Forum Post dorthin wo sie gehören? ....... in dem Editor sehen sie gut aus :thinking:
»SimonTheVillain« hat folgende Bilder angehängt:
  • Screenshot 2015-06-07 00.23.10.png
  • Screenshot 2015-06-07 00.30.26.png

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

2

07.06.2015, 09:13

Ich kenn mich zwar mehr mit DirectX aus, aber ich hab trotzdem ein paar Gedanken dazu:

- Also, bei glDrawArrays muss nicht zwangsweise ein Paket an die GPU übermittelt werden, aber wenn der Treiber es für sinnvoll hält kann er das trotzdem tun.
- Warum rufst du überhaupt glFinish auf?
- Zur GPU Auslastung: Laut dem Code zeichnest du nur ein paar Quads. Damit langweilt sich auch deine iGPU, außer deine Shader sind sehr, sehr aufwendig.
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

3

07.06.2015, 11:52

Ich kenn mich zwar mehr mit DirectX aus, aber ich hab trotzdem ein paar Gedanken dazu:

- Also, bei glDrawArrays muss nicht zwangsweise ein Paket an die GPU übermittelt werden, aber wenn der Treiber es für sinnvoll hält kann er das trotzdem tun.
- Warum rufst du überhaupt glFinish auf?
- Zur GPU Auslastung: Laut dem Code zeichnest du nur ein paar Quads. Damit langweilt sich auch deine iGPU, außer deine Shader sind sehr, sehr aufwendig.
Ja, der Fragment Shader ist ziemlich aufwändig. (es wird für jedes Fragment ein Sortieralgorithmus abgearbeitet und eine Funktion minimiert)
Das glFinish ist nur ganz am Schluss um die Berechnung zu beenden und um die Zeit zu nehmen notwendig.

Du musst dir OpenGL als CommadBuffer vorstellen, der nur Befehle cached und Sie dann Zeichnet, wenn der Treiber es für richtig hält.
Also das ganze ist Asynchron bis glFinish/glflush aufgerufen wird. Daher dauert der glfinish Call auch so lange.
Das ganze ist dafür, da dass Optimierungen vorgenommen werden können.

Du musst schon mehr ins Detail gehen, was du zeichnest, was du für ne Framerate haben willst usw.
Hmm. Ja, das mit dem commandBuffer deckt sich mit meinem Bild von OpenGL darum frage ich mich auch wieso glDrawArrays so viel Zeit in Anspruch nimmt. Ich hätte eher vermutet, dass glDrawArrays etwa so viel Zeit in Anspruch nimmt wie glBindTexture und nicht das zigfache.


Wie gesagt ich zeichne nichts. Es ist im Prinzip ein Iteratives Verfahren in der Art§x_{k+1}=f(x_k)§ wobei §x_{k+1}§ und §x_k§ zwei Texturen sind deren rollen immer wieder getauscht werden. Das blöde ist eben, dass ich 1500 Iterationen für eine ordentliche Konvergenz benötige. (zwischendurch muss auch der Shader gewechselt werden aber das ist nicht so extrem häufig.)
Wegen Framerate..... ich will auf 30ms(eher 20) für den Optimierungsprozess kommen benötige aber noch etwa 750ms auf dem Apple gerät.
Ich weiß, dass es CUDA Implementierungen von ähnlichen Algorithmen gibt die das schaffen. CUDA kommt für mich eben nicht in frage, weil ich keine Nvidia GPU habe und weil mir die Schnittstelle zu proprietär ist. Wenn es mit OpenGL nicht klappt werd ich eben auf OpenCL umsteigen. Aber zuerst würde ich gerne sehen ob sich da etwas machen lässt.

EDIT: Ich hab das ganze jetzt nochmal auf der Apple Hardware unter linux durchgeführt...... es läuft einfach genauso langsam wie unter OS X! Ich denke die Lösung zu dem Ganzen wäre irgendwie zu verhindern, dass ich ständig zwischen Texturen hin und her wechseln muss. Und auch das reduzieren der draw calls. Der Algorithmus erlaubt das aber irgendwie nicht.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »SimonTheVillain« (07.06.2015, 14:11)


Powerpaule

Treue Seele

Beiträge: 162

Wohnort: Berlin

Beruf: Softwareentwickler

  • Private Nachricht senden

4

07.06.2015, 13:53

Und beide Texturen die ganze Zeit aktiviert zu haben mit 2 samplern geht nicht? Dann würde zumindest das Wechseln wegfallen. Wobei das womöglich nicht so viel ausmacht. Was für ein Sortier-Algo ist das? Kann auch sein dass ein Großteil der GPU-Cores die meiste Zeit nichts tut, und das dann so ausbremst.
Ansonsten wäre OpenCL für sowas wirklich besser - da hast du einfach mehr Flexibilität und kannst in diveser Speicherblöcke schreiben, wie du willst. Hab OpenCL in meiner Masterarbeit für Path Tracing benutzt, wo es auch mehrere Hundert bis Tausend Iterationen braucht, bis man eine einigermaßen gute Konvergenz hat.

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

5

07.06.2015, 14:30

Hast du mal Compute Shader versucht?
Die normale Renderpipeline sollte einiges an Overhead verursachen.

6

07.06.2015, 14:32

Und beide Texturen die ganze Zeit aktiviert zu haben mit 2 samplern geht nicht? Dann würde zumindest das Wechseln wegfallen. Wobei das womöglich nicht so viel ausmacht. Was für ein Sortier-Algo ist das? Kann auch sein dass ein Großteil der GPU-Cores die meiste Zeit nichts tut, und das dann so ausbremst.
Ansonsten wäre OpenCL für sowas wirklich besser - da hast du einfach mehr Flexibilität und kannst in diveser Speicherblöcke schreiben, wie du willst. Hab OpenCL in meiner Masterarbeit für Path Tracing benutzt, wo es auch mehrere Hundert bis Tausend Iterationen braucht, bis man eine einigermaßen gute Konvergenz hat.
An das mit den beiden Samplern habe ich auch schon gedacht. Aber dann bräuchte ich einen Uniform, der mir anzeigt welche der beiden Texturen gerade aktiv ist, bzw. einen Wechsel des GLSL Programms. Es ist ein Bubblesort. Aber eine Veränderung der Anzahl der zu sortierenden Elemente wirkt sich nicht so besonders aus..... also denke ich nicht, dass ich mit Quicksort so viel bewirken kann. (es sind ohnehin nur max 14 Elemente die sortiert werden können).
Ja, ich werde bei Gelegenheit eine OpenCL portierung anstreben. Bin nur etwas enttäuscht, dass ich das nicht mit OpenGL hinbekommen habe. Vielleicht warte ich aber noch ab bis Mesa bzw. Apple endlich Compute Shader (OpenGL 4.3) unterstützen. Dann muss ich von den Leuten, die diesen Code verwenden werden nicht verlangen eine weitere Library zu installieren.

Powerpaule

Treue Seele

Beiträge: 162

Wohnort: Berlin

Beruf: Softwareentwickler

  • Private Nachricht senden

7

07.06.2015, 14:43

An das mit den beiden Samplern habe ich auch schon gedacht. Aber dann bräuchte ich einen Uniform, der mir anzeigt welche der beiden Texturen gerade aktiv ist, bzw. einen Wechsel des GLSL Programms. Es ist ein Bubblesort. Aber eine Veränderung der Anzahl der zu sortierenden Elemente wirkt sich nicht so besonders aus..... also denke ich nicht, dass ich mit Quicksort so viel bewirken kann. (es sind ohnehin nur max 14 Elemente die sortiert werden können).
Dann kannst du das mit den beiden Samplern ja mal einbauen - schaden sollte es jedenfalls nicht, und vielleicht bringt es ja was. Das extra flag brauchst du dann natürlich, ja. Programwechsel wäre nicht so gut, das ist nochmal viel langsamer als die Texturwechsel.
Und dann kann man ja nochmal weiter gucken. Quicksort macht da sicher keinen Sinn, ja. Zumal man auch nicht davon ausgehen darf, dass Algorithmen, die auf der CPU gut laufen, auf der GPU ähnlich viel bringen. Manchmal ist auch das Gegenteil der Fall.

8

07.06.2015, 16:40

Da das ganze jetzt Beruflich ist darf ich nicht viel dazu sagen, aber ich lehn mich mal aus dem Fenster und sage es geht darum die Tiefe zu berechnen wenn man mehr als 2 Kameras hat. (z.b. 14)
Jedenfalls werd ich mich wieder melden wenn ich es geschafft habe den Code etwas zu optimieren..... ich komm in den nächsten Tagen leider nicht dazu.
Danke jedenfalls. :thumbup:

Werbeanzeige