OpenGL: Suche nach Performanceverschwendung
-
Ich bräuchte ein paar Anregungen, wie ich die Performance meiner 3D Engine ausbauen kann.
http://vertex.art-fx.org/dreide222.zip das ist die neuste Version inklusive Quellcode.
Hintergrund ist dieser, das ich immer mit einer fertigen 3D Engine vergleiche. Konkret: meine hatte 190 FPS die Vergleichsengine(Blitz3D) 320 FPS.
Ich zeige euch einfach mal den Renderpass, der in diesem Beispiel konkret abläuft:
Kamera: glDisable(GL_SCISSOR_TEST) // Da der Viewport den gesamten Bereich einnimmt. glMatrixMode(GL_PROJECTION) glLoadIdentity() glViewport(0, 0, 800, 600) gluPerspective(45.0/1.0, Float(800)/Float(600), 1.0, 1000.0) glScalef(1.0, 1.0, 1.0) glEnable(GL_DEPTH_TEST) glDepthFunc(GL_LEQUAL) glClear(GL_DEPTH_BUFFER_BIT) glClearColor(0.4, 0.6, 0.8, 1.0) glClear(GL_COLOR_BUFFER_BIT) glDisable(GL_FOG) glMatrixMode(GL_MODELVIEW) glLoadIdentity() glRotatef(-Self.Rotation[0], 1.0, 0.0, 0.0) glRotatef(-Self.Rotation[1], 0.0, 1.0, 0.0) glRotatef(-Self.Rotation[2], 0.0, 0.0, 1.0) glPushMatrix() Mesh-Rendern glPopMatrix() Mesh-Rendern: glTranslatef(Self.Position[0], Self.Position[1], Self.Position[2]) glRotatef(Self.Rotation[0], 1.0, 0.0, 0.0) glRotatef(Self.Rotation[1], 0.0, 1.0, 0.0) glRotatef(Self.Rotation[2], 0.0, 0.0, 1.0) glScalef(Self.Scale[0], Self.Scale[1], Self.Scale[2]) Alle Surfaces durchgehen { Surface-Rendern } Surface-Rendern: Materialeigenschaften-Setzen: glEnable(GL_CULL_FACE) glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, 0.0) glShadeModel(GL_SMOOTH) glPolygonMode(Face, GL_FILL) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glMaterialf(Face, GL_SHININESS, Self.Shininess) glMaterialfv(Face, GL_AMBIENT, Self.AmbientColor) glMaterialfv(Face, GL_DIFFUSE, Self.DiffuseColor) glMaterialfv(Face, GL_SPECULAR, Self.SpecularColor) glMaterialfv(Face, GL_EMISSION, Self.EmissiveColor) glEnableClientState(GL_TEXTURE_COORD_ARRAY) // Textur aktivieren glActiveTexture(GL_TEXTURE0) glBindBufferARB(GL_ARRAY_BUFFER, Self.VertexBuffer[2]) glTexCoordPointer(2, GL_FLOAT, 0, Null) Textureeigenschaften-Setzen: glGetIntegerv(GL_MATRIX_MODE, Varptr(Matrix)) glMatrixMode(GL_TEXTURE) glLoadIdentity() glTranslatef(Self.Position[0], Self.Position[1], 0.0) glRotatef(Self.Rotation, 0.0, 0.0, 1.0) glScalef(Self.Scale[0], Self.Scale[1], -1.0) glMatrixMode(Matrix) glDisable(GL_TEXTURE_CUBE_MAP) glDisable(GL_TEXTURE_GEN_S) glDisable(GL_TEXTURE_GEN_T) glDisable(GL_TEXTURE_GEN_R) glEnable(GL_TEXTURE_2D) glBindTexture(GL_TEXTURE_2D, Self.TextureID) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT) glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE) // Bind Vertex-Color glBindBufferARB(GL_ARRAY_BUFFER, Self.VertexBuffer[4]) glColorPointer(4, GL_FLOAT, 0, Null) // Bind Normals glBindBufferARB(GL_ARRAY_BUFFER, Self.VertexBuffer[1]) glNormalPointer(GL_FLOAT, 0, Null) // Bind Vertices glBindBufferARB(GL_ARRAY_BUFFER, Self.VertexBuffer[0]) glVertexPointer(3, GL_FLOAT, 0, Null) // Bind TriangleBuffer glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, Self.TriangleBuffer) // Display Triangles glDrawElements(GL_TRIANGLES, Self.TriangleCount*3, GL_UNSIGNED_INT, Null)So sieht der Renderpass für ein Mesh mit 8000 Triangles, 16 Surfaces, 10 Materials und 3 Texturen aus.
Wo hängt die größte Performance? Ist meinetwegen das ständige Deaktivieren des Scissor-Tests sehr verschwenderich? Also soetwas in der Richtung.
Danke schonmal, wer sich die Mühe macht, mir fehlt es einfach noch an Erfahrung mit OpenGL.
mfg olli
-
würd einfach mal um jede Operation nen Timer setzen und das Ergebnis in eine Datei schreiben, dann weißte, was am meisten Zeit beansprucht..
-
oder durch nen profiler jagen. mit mingw und gprof geht das sehr easy...
-
Ja, ich abreite hier mit BlitzMax und nicht mit MingW...
Habe jetzt mal fast alle Befehle gemessen:
glDisable(GL_SCISSOR_TEST) = 666 ms glMatrixMode(GL_PROJECTION) = 145 ms glLoadIdentity() = 607 ms glViewport(0, 0, 800, 600) = 820 ms gluPerspective(45.0/1.0, Float(800)/Float(600), 1.0, 1000.0) ~ 590100 ms glScalef(1.0, 1.0, 1.0) = 621 ms glEnable(GL_DEPTH_TEST) = 734 ms glDepthFunc(GL_LEQUAL) = 471 ms glClear(GL_DEPTH_BUFFER_BIT) ~ 1400 ms (nicht messbar) glClearColor(0.4, 0.6, 0.8, 1.0) = 1663 ms glClear(GL_COLOR_BUFFER_BIT) ~ 2000 ms (nicht messbar) glDisable(GL_FOG) = 851 ms glMatrixMode(GL_MODELVIEW) = 105 ms glRotatef(-127.5, 1.0, 0.0, 0.0) = 3634 ms glPushMatrix() + glPopMatrix() = 1451 ms glTranslatef(10.0, 20.0, 30.0) = 590 glScalef(10.0, 20.0, 30.0) = 12863 ms -------------------------------------------------------------------------------- glEnable(GL_CULL_FACE) = 482 ms glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, 0.0) = 632 ms glShadeModel(GL_SMOOTH) = 418 ms glPolygonMode(GL_FRONT, GL_FILL) = 505 ms glEnable(GL_BLEND) = 993 ms glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) = 393 ms glMaterialf(GL_FRONT, GL_SHININESS, 0.6) = 1106 ms glMaterialfv(GL_FRONT, GL_XXXXX, [0.2, 0.3, 0.4, 0.5]) ~ 391260 ms glEnableClientState(GL_TEXTURE_COORD_ARRAY) = 177 ms -------------------------------------------------------------------------------- glActiveTexture(GL_TEXTURE0) = 123 ms glGetIntegerv(GL_MATRIX_MODE, Varptr(Matrix)) = 143 ms glMatrixMode(GL_TEXTURE) = 130 ms glDisable(GL_TEXTURE_CUBE_MAP) = 211 ms glDisable(GL_TEXTURE_GEN_S) = 171 ms glDisable(GL_TEXTURE_GEN_T) = 280 ms glDisable(GL_TEXTURE_GEN_R) = 189 ms glEnable(GL_TEXTURE_2D) = 370 ms glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT) = 598 ms glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE) = 385 msDie Zeiten mit ~ musste ich aufrunden. glClear hat mein Rechner mehrmals abschmieren lassen.
Das Meiste ist einfach nur Overhead, aber folgendes kann man Schlussfolgern:
- glClear immer mit allen Buffern gemeinsam aufrufen
- gluPerspective so wenig wie möglich aufrufen(event. eigene Rotine schreiben)
- glMaterialfv so wenig wie möglich verwendenWas auch ganz interessant ist, dass glScale treiber- oder hardwarenäßig optimiert wurde. Wenn ein Parameter = 1.0 ist, so wird dieser anscheinend nicht beachtet.
Die ganzen Tests liefen auf:
Vendor: Intel Renderer: Intel 915G OpenGL-Version: 1.4.0 - Build 4.14.10.4020 Prozessor: Intel pentium 4 CPU 2.80GHz (2 CPUs), ~2.8GHz Arbeitsspeicher: 1014MB RAM OS: Win2000 prof.mfg olli
-
Schau mal "Bottleneck Identification" auf diesen Folien an: http://www.ati.com/developer/gdc/PerformanceTuning.pdf
-
glScalef(10.0, 20.0, 30.0) = 12863 ms
12 Sekunden für nen glScalef

Da ist aber etwas sehr übel! Oder steht ms nicht für Millisekunden (1 /1000)?
-
Andreas XXL schrieb:
glScalef(10.0, 20.0, 30.0) = 12863 ms
12 Sekunden für nen glScalef

Da ist aber etwas sehr übel! Oder steht ms nicht für Millisekunden (1 /1000)?
Nicht für ein glScalef sondern für alle glScalef zusammen, die das Programm aufgerufen hat.