Grafikkarte in die Knie zwingen! (OpenGL)



  • Hi, ich schreibe einen Performancetest für JOGL. Dait das JNI nicht der Flaschenhals ist, sondern die Grafikkarte, benötige ich ein ein OpenGL-Prog,
    das mit wenigen Befehlen die grafikkarte in die knie bekommt, bevor das JNI in die Knie geht. Kennt jemand da einfache Graffikartenlastige OpenGL-Befehle und wie ich diese Anwende. Bin selber nur Anfänger mit openGL 😞



  • Wenn du speziell JOGL testen willst, ist das aber IMHO der falsche Ansatz. Das, was man JOGL an Langsamkeit unterstellen könnte ist ja genau das JNI. Dass der Rest nicht viel langsamer wird, kannst du dir an einer Hand abzählen.



  • Nein..das kann man eben nicht an einer Hand abzählen 🙂
    Das JNI habe ich zur genüge getestet. Viel kurzlebige OpenGL-Befehle bewirken
    das JOGL in etwa um 2/3 langsamer ist, als ein gleiches Programm in C.
    Das liegt an dem JNI-Flaschenhals. Nun muss ich für eine Ausarbeitung noch beweisen können, dass ohne den JNI Flaschenhals JOGL ungefähr gleich schnell ist wie ein dazugehöriges C Programm.

    Meine Testergebnisse:

    Test1:
    Hauptschleife mit JOGL mit nur einem OpenGL-Befehl pro Schleife: 2580 FPS
    Hauptschleife mit C mit nur einem OpenGL-Befehl pro Schleife: 5651 FPS

    Test2:
    Hauptschleife mit JOGL mit 66K kurzlebigen OpenGL-Befehlen pro Schleife: 206 FPS
    Hauptschleife mit C mit 66K kurzlebigen OpenGL-Befehlen pro Schleife: 550 FPS

    Diese Test habe ich ausführlich geplant und sehr genau implementiert.
    Sie müssten einen ungefähren Richtwert liefern.

    Nun stehe ich vor dem Problem, wie bekomme ich bei beiden eine ungefähre gleiche FPS hin wenn der JNI-Flaschenhals irrelevant ist.

    Mein Denkansatz war:

    Wenig OpenGL-Befehle, massig Rechenarbeit für die GPU, sodass der Flaschenhals
    des JNI nicht mehr zum tragen kommt, sondern die Grafikarte der Flaschenhals ist. Das bedeutet ich heize der Graka ein bis die FPS aufgrund DIESER langsam runtergehen werden, somit sollten C und JOGL hier ungefähr gleich abschneiden.
    Oder habe ich da nen Denkfehler drinnen ?

    Ich habe schon folgendes ausprobiert: Wenig Befehle, Mords-Polygone

    GLUquadric * qobj0 = gluNewQuadric();
    gluQuadricDrawStyle(qobj0, GLU_LINE);
    gluQuadricNormals(qobj0, GLU_SMOOTH);
    gluSphere(qobj0, 0.1f, 1000000, 1000000);
    gluDeleteQuadric(qobj0);

    Das packt aber Java garnicht und bekommt nur 1 FPS !
    Das C-Programm schafftda allerdings noch 270 FPS.
    irgendwie klappt das so nicht ?! 😞



  • naja, gluSphre und sowas, sind nciht grafikkarten-lastig (glaub ich).
    Was passiert denn in der Funktion? Es werden vertex-Koordinaten für eine Kugel berechnet. Das dauert natürlich in Java länger als in C (hat nichts mit der Graka zu tun).
    Ich denke wirklich schwierig für die Graka wird es, wenn du total komplizierte Shader (vertex und pixel) nimmst, (da die auf der Graka berechnet werden), und pro Frame nicht viel renderst, sondern nur einige Dreiecke (damit du den AGP-Port nicht überlastest) oder aus Vertexbuffers (so heißen die in D3D, kA wie die in ogl heißen) renderst.
    Die Grafikkarte hat viel zu berechnen, wenn du kranke effekte wie reflektionen, fisheye und so machst. Dazu natürlich mindestes 10 spotlights (sofern die Graka die hw-mäßig unterstützt). Also nichts machen, was speicherlastig ist, sondern was viel arbeit erfordert beim darstellen.



  • Vielen Dank Maxi..und das genau ist meine Frage..weiss da jemand auf die schnelle nen paar Methoden in OpenGL die ich benutzen kann ? Ich habe garkeine Ahnung womit ich anfangen soll...mit shading und so habe ich noch nie gearbeitet 😞



  • Render doch einfach 1000 bildschirmfüllende Rechtecke (evtl. noch mit einer Textur) und Alpha-Blending.

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);
    
    glBegin(GL_QUADS);
    
    for(int i = 0; i < 1000; i++)
    {
        glVertex2i(-1, 1);
        glVertex2i(1, 1);
        glVertex2i(1, -1);
        glVertex2i(-1, -1);
    }
    
    glEnd();
    

    Du kannst das noch in eine Display-Liste packen. Dann brauchst du nur glCallList aufzurufen.



  • Wow...habe das einmal in C und einmal in JOGL implementiert und es KLAPPT!

    C hat hierbei : 18 FPS
    JOGL hat exakt: 18 FPS

    habe das so implementiert:

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);
    
    glNewList(1234 ,GL_COMPILE); 
    glBegin(GL_QUADS);
    for(int i = 0; i < 1000; i++)
    {
    glVertex2i(-1, 1);
    glVertex2i(1, 1);
    glVertex2i(1, -1);
    glVertex2i(-1, -1);
    }
    glEnd();
    glEndList();
    
    ....
    ....
    
    //Hauptschleife
    glTranslatef(0.0f, 0.0f, -5.0f);
    glCallList(1234);
    

    Sollte doch so sein oder ? Wusste nicht ob die For-Schleife mit in die Display-Liste darf ?

    Jedenfalls scheint es zu funktionieren! Kannst du mir noch bitte kurz erklären warum es funktioniert und warum es so Grafikkartenlastig ist ?
    Mein Programm hatte mindestens 1000 3D-Würfel mit Texturen und allem drumm und drann und hat nicht annähernd soviel Performance gegessen, wie dein Performance-Monster, welches du da gezüchtet hast 😃



  • Hmm habe mich zu früh gefreut..kann es sein das die Hauptschleife immer wartet, bis die DisplayListe abgearbeitet ist ??

    Mich wundert es erstens..dass wenn ich die 1000 Vierecke rendere, C und auch JOGL nur noch so 18 FPS haben. Das is mehr als wenig. Ok dachte ich..dann frisst halt Alphablending soviel! Aber wenn ich Alphablending ausschalte verändert sich net allzuviel. Dann habe ich einfach mal mit einer DisplayListe nur 100 vierecke
    gerendert und wieder JOGL und C haben die gleiche Framerate von 270!!
    Das ist doch vieeel zu wenig für 100 vierecke ! Zumal ich ja Alphablending ausgeschaltet habe. Bekomme ja schon mit meinem Perfermancetest ohne displaylisten 1000 Vierecke mit Texturen bei 500FPs hin. Das kann alles nicht sein ?

    Dann habe ich den ultimativen Test gemacht und nur ein einziges Viereck in eine DisplayList gepackt und dann wieder mit c und einmal mit JOGL gerendert. Ergebnis:beide exakt 1840 FPS. DisplayListen scheinen langsamer zu sein und die Hauptschkleief wartet auf diese! anders kann ich mirs nicht vorstellen, dass nun JOGL und C so dermaßen synchron laufen.



  • liegt vllt daran das der flaschenhals dann dein CPU ist 😉

    ich kenn mich jetzt nicht mit oGL grossartig aus (hab mal gelesen wenn man ein Engine machen will was beides (DX u. OGL) nutzt sollte man virtuelle interface erstellen -> OGL weicht nicht sooo viel von DX ab ...

    wenn ich das jetzt so richtig verstehe sind JNI ist die API für JOGL - was auf OGL basiert ?!

    ist klar das es langsamer ist als OGL per c(++), c++ ist die (unkompiliert)nativ sprache (assembler) -> die schnellste schneller als c++ kanns ja gar nimmer gehen - drum auch die verhältnisse

    warum es mit dem performance monster sooo in die knie geht weis ich jetzt nicht genau aber schätzungsweisse packts der CPU nicht so 100%ig 😉



  • TomasRiker schrieb:

    Render doch einfach 1000 bildschirmfüllende Rechtecke (evtl. noch mit einer Textur) und Alpha-Blending.

    Wollt ich auch grad sagen...

    Und nein, euer ganzen Gequatsche von "zu langsam" ist Unsinn, so schnell ist eine GraKa nun mal. Rechnet mal aus, wieviel Pixel gemalt werden und vergleicht mit der theoretischen Fuellrate, ihr Dropse. f'`8k

    Autocogito

    Gruß, TGGC (\-/ has leading)


Log in to reply