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

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

41

24.02.2012, 00:28

Wenn du einfach nur 20000 Mal direkt hintereinander die selben 2 VBOs bindest, wird das natürlich praktisch keine Auswirkungen haben, da die entsprechenden Caching-Effekte kaum auftreten werden. Ich denk, dass du da oben effektiv wenig mehr tust, als den reinen Function-Call-Overhead zu messen.
Ein potentiell relevanter Einfluss auf die Performance, wird vermutlich erst im Kontext mit einer richtigen Anwendung, die mehr macht als ein paar OpenGL Calls abzusetzen, messbar werden. Wenn du da im Hintergrund ein paar OGG Streams decodest und z.B. noch irgendwelche Gamelogik betreibst, könnt ich mir aber vorstellen, dass sich das schon bemerkbar macht.

btw: Weil du von 60 fps berichtest, muss ich noch fragen, ob du eh nicht vergessen hast VSync abzuschalten? ;)

Abgesehen davon gings mir eigentlich eher um die prinzipiellen Probleme dieses "bind and use" Modells, wie z.B. eben, dass es unnötig kompliziert ist, unnötigen globalen Zustand einführt und eben nicht wirklich mit OOP kompatibel ist (auch wenn ich es schon als eine Art von Objektorientierheit verstehen würde).
Die Tatsache dass es unnötigerweise ineffiziente Operationen im Grafiktreiber erzwingt, find ich unschön, aber nicht so gravierend wie die Auswirkungen auf der anderen Seite der API.
Mit der Einfürhung von VAOs ist das mittlerweile vermutlich auch weniger relevant.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »dot« (24.02.2012, 00:38)


stef

Treue Seele

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

42

24.02.2012, 00:50

Wo liegt eigentlich der Unterschied zwischen dem BIND von OpenGL und den Methoden SetStreamSource (für Buffer) und SetTexture (für Texturen) von D3D ?
Ist das bis auf den Namen nicht im wesentlichem das Selbe ? (Allerdings weis ich nicht ob es das bei Dx10 und Dx11 noch gibt.)

@Dot: Danke fürs Code-Formatieren !
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

43

24.02.2012, 01:46

Wo liegt eigentlich der Unterschied zwischen dem BIND von OpenGL und den Methoden SetStreamSource (für Buffer) und SetTexture (für Texturen) von D3D ?
Ist das bis auf den Namen nicht im wesentlichem das Selbe ? (Allerdings weis ich nicht ob es das bei Dx10 und Dx11 noch gibt.)

Natürlich ist es konzeptionell das selbe, darum geht's ja nicht.
Es geht darum, dass das Objektmodell von OpenGL durch dieses herumgebinde alles unötig verkompliziert und dabei auch unnötigen Overhead mit sich bringt.
Zunächst mal übergibst du in Direct3D an SetStreamSource() bzw. IASetVertexBuffers() direkt einen Pointer auf das entsprechende Buffer-Objekt und das wars.
In OpenGL musst du erstmal den VBO-Name an ein Target binden, was bedeutet, dass der Grafiktreiber das eigentliche Objekt erstmal aus irgendeiner Map suchen darf.
Das Hauptproblem in OpenGL seh ich dann eben genau in der Trennung zwischen der id und den eigentlichen Daten, kombiniert mit diesem System globaler Bind-Targets. Das eigentliche Objekt hinter einer id kann sich nämlich ändern. Sobald ich glBufferData(), glTexImage2D() und dergleichen aufrufe, mach ich ja effektiv nichts andres als ein neues Objekt zu erstellen.
Man könnte sagen, "Objekte" in OpenGL leiden unter einer ganz merkwürdigen Form von Persönlichkeitsspaltung.

Aber eigentlich kann man die beiden APIs aufgrund der strukturellen Unterschiede in diesem Fall imo schwer sinnvoll vergleichen. Ich wollte auch nicht behaupten, dass diese Sache OpenGL einen Performancenachteil im Vergleich zu Direct3D einbringt (iirc verwendet Direct3D an der Schnittstelle zum Treiber selbst eine handlebasierte API, allerdings ist das eben aufgrund des wesentlich anderen Designs von Direct3D wohl nicht problematisch). Denn wie gesagt hab ich die beiden APIs selbst noch nie direkt verglichen was die Performance angeht und mir wäre auch sonst bisher kein irgendwie praktisch relevanter Performanceunterschied aufgefallen.
Wenn ich wirklich mal Performanceprobleme mit OpenGL hatte, so war das bisher eigentlich immer auf schlechte Treiber (Intel...) zurückzuführen.
Und mit der Einführung von VAOs ist diese konkrete Angelegenheit vermutlich nichtmehr so relevant.

Der Grund wieso ich das erwähnt hab war eben, dass die "Objektorientiertheit" von Direct3D kritisiert wurde und ich daraufhin zeigen wollte, dass OpenGL auf seine eigene, aber sehr kaputte Art objektorientiert ist und wo ich die Probleme dieses Objektmodells sehe. Direct3D mapped trotz bzw. eben gerade wegen seines objektorientierten Designs wesentlich besser auf die tatsächliche Hardware als OpenGL.
Das Problem von OpenGL ist, dass die API ihre Wurzeln in den 80er Jahren hat und seither, was diese Dinge angeht, keine wesentlichen Änderungen durchgemacht hat, obwohl es wirklich, wirklich mal dringend notwendig wäre...

Dieser Beitrag wurde bereits 12 mal editiert, zuletzt von »dot« (24.02.2012, 02:21)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

44

24.02.2012, 06:38

Zitat

Durch das merkwürdige Objektmodell (der ganze Bind Kram), ist das entweder nur sehr ineffizient möglich ...
Ich habe das aus Interesse gerade mal ausprobiert indem ich in meiner Render-Loop in einer For-Schleife via BIND eine Texture und drei Buffer swappe. Einen Einfluß auf meine Framerate hat das erst wenn die For-Schleife 20000 durchlaufen wird (also 20000 Texture- und 60000 Buffer-Swaps pro Render pass). So ein performancekiller kann das also nicht sein.

Ich weigere mich diese Messung zu glauben. Ein einziges VBO-Bind führt bei mir schon zu einer Änderung der Performance. Kann es eventuell sein, dass Du schlecht gemessen hast? Sowas wie ein Rendering gemacht, was mit 300 FPS läuft, aber durch einen TFT-Monitor auf 60 FPS reduziert wird und erst nach Deinen 20k-Binds (die wie dot schon sagte ohnehin keine gute Messgröße sind, dank fehlender Caching-Problematik, etc) unter 60 FPS fällt?
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

stef

Treue Seele

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

45

24.02.2012, 08:16

Zitat

Ich weigere mich diese Messung zu glauben. Ein einziges VBO-Bind führt bei mir schon zu einer Änderung der Performance. Kann es eventuell sein, dass Du schlecht gemessen hast? Sowas wie ein Rendering gemacht, was mit 300 FPS läuft, aber durch einen TFT-Monitor auf 60 FPS reduziert wird und erst nach Deinen 20k-Binds (die wie dot schon sagte ohnehin keine gute Messgröße sind, dank fehlender Caching-Problematik, etc) unter 60 FPS fällt?

Sorry, ich habe mich da etwas unglücklich ausgedrückt und du hast natürlich recht. Wie DOT schon festgestellt hat habe ich VSync aktiviert, laufe also mit meinem TFT auf 60 fps und meine GK langweilt sich eigentlich zu tode. Erst wenn die For-Schleife innerhalb meiner Render-Loop mehr als 20000 mal durchlaufen wird werden die 60fps unterschritten. Natürlich hat jeder VBO-Bind einen Einfluß auf die Performance und wenn ich ohne VSync arbeiten würde hätte ich bereits einen Performance Einbruch wenn die For-Schleife nur 1000 mal durchlaufen wird. (Habe es gerade mal probiert 2700fps ohne For-Schleife, 1200fps bei 1000 loops und 72fps bei 20000 loops). Ich wolte auch nur mal sehen ab welcher Grenze die Sache sprürbar wird (fps < 60).

Übrigens halte ich das mit dem Caching nur bedingt für zutreffend da jeder Bind Aufruf auch irgendwo eine Speicheränderung mit sich bringt. (Änderung von States / Zeigern usw.)
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

46

24.02.2012, 16:17

Ich wolte auch nur mal sehen ab welcher Grenze die Sache sprürbar wird (fps < 60).

Das kannst Du so pauschal auch nicht sagen. Wenn Dein Game gerade so 60 FPS schafft (also eine Frametime, die knapp unter 1/60 Sekunde liegt), dann können schon sehr wenige solcher Binds dazu führen, dass sie auf 30 FPS sinkt (nämlich bei einer Frametime konstant größer als 1/60 Sekunde), wenn VSynch an ist. Die GPU wird sich dann fast einen Frame über langweilen (die Zeit bis zum nächsten VSynch), aber wenn das Rendering eben nicht innerhalb der Zeit von einem VSynch zum nächsten machbar ist (und das jeden Frame reproduzierbar), dann haste schnell argen Ärger.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

stef

Treue Seele

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

47

24.02.2012, 16:43

Das kannst Du so pauschal auch nicht sagen. Wenn Dein Game gerade so 60 FPS schafft (also eine Frametime, die knapp unter 1/60 Sekunde liegt), dann können schon sehr wenige solcher Binds dazu führen, dass sie auf 30 FPS sinkt (nämlich bei einer Frametime konstant größer als 1/60 Sekunde), wenn VSynch an ist. Die GPU wird sich dann fast einen Frame über langweilen (die Zeit bis zum nächsten VSynch), aber wenn das Rendering eben nicht innerhalb der Zeit von einem VSynch zum nächsten machbar ist (und das jeden Frame reproduzierbar), dann haste schnell argen Ärger.

Ist schon klar ...
Wenn dein Renderer mit VSync knapp auf Kante läuft kann theoretisch schon das Bewegen der Mouse ausreichen um die FR stark zu reduzieren.
In keinem Fall ist dann aber das Aufrufen von Bind-Funktionen der Flaschenhals.
(Es sei denn du machs es 20000 mal in einer For-Schleife ;) )
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

48

24.02.2012, 16:44

Na sagen wir's mal so: Durch ungünstige Verwendung von VBOs habe ich schon mal 30% mehr Frametime gehabt als der Immediate Mode... Das ist nur zurückzuführen auf die mistige Art wie Binds in GL laufen, denn die Calls und Speicher-Bewegung war mit VBO-Verwendung deutlich weniger.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige