Performance-Optimierung?



  • Hallo, ich habe folgenden Code:

    float vx[30000], vy[30000], vz[30000];
    float cred[30000], cgreen[30000], cblue[30000];
    float x_0[30000], y_0[30000], z_0[30000];
    float dirx[30000], diry[30000], dirz[30000];
    float dx[30000], dy[30000], dz[30000];
    float r[30000];
    
    float t = 0.0f;
    
    inline float mod(double a, double b) {
    	int res = static_cast<int>( a/b );
    	return a - static_cast<float>( res ) * b;
    }
    
    void renderScene(void) 
    {
        glMatrixMode(GL_MODELVIEW);                             //make sure we aren't changing the projection matrix!
        glLoadIdentity();
        gluLookAt(cameraX, cameraY, cameraZ,                    //camera is located at (x,y,z)
                  cameraX+dirX, cameraY+dirY, cameraZ+dirZ,		//camera is looking at at (x,y,z) + (dx,dy,dz) -- straight ahead
                  0.0f, 1.0f, 0.0f);                            //up vector is (0,1,0) (positive Y)
    
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    	EasyGL_DrawGrid();
    
    	t += 0.5f;
    
    	float x2 = 0.0f, y2 = 0.0f, z2 = 0.0f;
    
    	for (int i = 0; i < 30000; ++i) {
    		glPushMatrix();
    
    		dirx[i] = abs(sin(M_PI/2 * floor( (x_0[i] + vx[i]*t)/(dx[i]) )));
    		diry[i] = abs(sin(M_PI/2 * floor( (y_0[i] + vy[i]*t)/(dy[i]) )));
    		dirz[i] = abs(sin(M_PI/2 * floor( (z_0[i] + vz[i]*t)/(dz[i]) )));
    
    		glColor3f(cred[i],cgreen[i],cblue[i]);
    		x2 = r[i] + abs((dx[i]) * dirx[i] - mod(x_0[i] + vx[i]*t, (dx[i])));
    		y2 = r[i] + abs((dy[i]) * diry[i] - mod(y_0[i] + vy[i]*t, (dy[i])));
    		z2 = r[i] + abs((dz[i]) * dirz[i] - mod(z_0[i] + vz[i]*t, (dz[i])));
    
    		glTranslatef(x2,y2,z2);
    		glutSolidCube(r[i]);
    
    		glPopMatrix();
    	}
    
        glutSwapBuffers();
    }
    

    Einige der Arrays, wie r[], y_0[], x_0[], z_0[], dx[], dy[], dz[] sind konstant, jedenfalls bisher. Also bei allen Quadern dieselben Werte. Ich habe nur Arrays gemacht, um später die Quader besser einstellen zu können. Leider ist der Code noch recht langsam, ca. 5-7 fps. Ich denke, die allermeiste Zeit braucht das Zeichnen, also OpenGL und GLUT. In Tests habe ich gesehen, dass abs(), sin() und floor() eigentlich recht flott sind.
    Also die Frage ist, wo man da noch was optimieren kann, sei es auch noch so klein. Jede Mikrosekunde zählt, ich träume von 30.000 Quadern bei 25 fps 😉

    Danke,

    Grüße,

    Thilo



  • OpenGL Aufrufe sind unfassbar CPU-intensiv. Die musst du minimieren. Wirklich jeder Aufruf, den du im Rendercode hast zählt. Wenn du viele gleiche Objekte hast, nutze Instancing. Geht am Anfang auch mit nem simplen Array im Shader. Dann sind auch 25k Würfel mit 60 FPS relativ problemlos. In einem echten Spiel würde man halt noch viel über "Occlusion Culling" etc. regeln. Es ist gar nicht so uneffektiv wie man denkt, sehr viel Zeit darin zu investieren, erst garnicht zum Zeichnen zu kommen.

    Das bisschen Rumgerechne da sollte eigentlich kaum Zeit verbrauchen wenn da OpenGL Aufrufe zwischen stecken.



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x und C++11) in das Forum Spiele-/Grafikprogrammierung verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


  • Mod

    Thilo87 schrieb:

    ... Ich denke, die allermeiste Zeit braucht ...

    ein gutes profiling tool ist sehr viel mehr wert als voodoo. lass die entsprechenden fuer cpu und gpu laufen und sag uns was wirklich limitiert.



  • Naja, in dem Beispiel isses wohl ziemlich offensichtlich, dass es die 30000 Draw Calls pro Frame sind 😉


  • Mod

    dot schrieb:

    Naja, in dem Beispiel isses wohl ziemlich offensichtlich, dass es die 30000 Draw Calls pro Frame sind 😉

    jo, steht da:

    for (int i = 0; i < 30000; ++i) {
    

    hatte ich vor kurzem in einem anderen forum genau so gesehen, scheinbar hatte ihm ein held empfohlen instancing zu implementieren, wurde aber garnicht schneller, oh wunder, er steht in mitten der boxen und zeichnet sie mit transparenz, komplett ROP bound.

    engineers profilen, priester glauben. 😉



  • Okay, ihr redet Chinesisch für mich. Aber ich werde mich mal mit Shadern auseinandersetzen, bin ja noch OpenGL-Anfänger 😉 Danke



  • Ich denk du könntest die Performance schon wesentlich verbessern, wenn du nur nicht jeden Würfel einzeln zeichnen würdest, sondern alle Würfel auf einmal. Also z.B. eben nicht pro Würfel glutSolidCube() aufrufen, sondern die Würfel selber malen und die Schleife dazu zwischen glBegin() und glEnd() packen und nicht glBegin() glEnd() in die Schleife...


  • Mod

    oder aber auch alles in eine renderlist compilieren und die dann nur immer ausfuehren lassen. ist 5min arbeit.

    [edit] dennoch empfehle ich zu profilen!



  • oder aber auch alles in eine renderlist compilieren und die dann nur immer ausfuehren lassen. ist 5min arbeit.

    Aber die Würfel bekommen im Laufe des Programmes verschiedene Positionen. Da müsste ich doch die Liste dann immer wieder von neuem compilieren, das wäre doch im Endeffekt derselbe aufwand, oder?



  • Thilo87 schrieb:

    Aber die Würfel bekommen im Laufe des Programmes verschiedene Positionen.

    In dem Fall schau einfach mal, was du rausholen kannst, wenn du die Schleifen umbaust, wie ich oben gesagt hab. Eine Displaylist bringt natürlich vor allem was bei statischen Daten...



  • wieso berechnest du eigentlich die richtung usw. in der zeichenfunktion oO



  • Schmeiß das uralt OpenGL auf den Müll, nimm Shader, implementiere rudimentäres Instancing und hab Spaß mit deinen 25k Würfeln.


  • Mod

    Thilo87 schrieb:

    oder aber auch alles in eine renderlist compilieren und die dann nur immer ausfuehren lassen. ist 5min arbeit.

    Aber die Würfel bekommen im Laufe des Programmes verschiedene Positionen. Da müsste ich doch die Liste dann immer wieder von neuem compilieren, das wäre doch im Endeffekt derselbe aufwand, oder?

    wie oft? wenn du einmal pro minute die liste generierst, bist du im schnitt vermutlich mit mehr fps unterwegs, als wenn du z.b. instanzing benutzt.

    aber wie gesagt, am ende sagt nur ein profiling tool wo das problem liegt, und dann kann man nach der richtigen optimierung greifen.


Anmelden zum Antworten