Hilfe! Member-Konstanten gleich als Feldindex?



  • Hm, direkt schneller als ein vector bzw. roher Zeiger/rohes Array (läuft aufs selbe hinaus) ist eigentlich nichts - man kann sonst noch darauf achten, dass die Daten für den Prozessor immer gut zugreifbar liegen. Außerdem könnte ich mir vorstellen, dass ein Zugriff auf vector<int>-Elemente schneller geht als auf die eines vector<char>, weil die an 32bit-Grenzen ausgerichtet werden etc. usw. - aber einen einfachen "schnelleren Container" kann ich mir nicht vorstellen.



  • Hm, direkt schneller als ein vector bzw. roher Zeiger/rohes Array (läuft aufs selbe hinaus)

    Läuft absolut nicht aufs selbe hinaus.
    Es geht ja nicht nur um den Zúgriff. Auch das Instanzieren braucht seine Zeit.
    Die Containerklasse vector ist dabei nicht gerade als optimal anzusehen ...



  • Knallhart zum Thema beigetragen 👍



  • operator void schrieb:

    Knallhart zum Thema beigetragen 👍

    Musste nunmal sein, wenn hier so'n Müll erzählt wird.



  • @rofl: Du hast sicher recht, jedoch bezog sich (denk ich mal) operator voids Beitrag auf meine Frage, wo ich ausschließlich vom Zugriff sprach.
    Tja, wenn der Vector beim Zugriff genauso schnell ist wie ein normales Array (oder fast) dann kann die miese Performance (Prog läuft noch 1/3 so schnell wie vorher mit C) eigentlich nur noch an der Zuweisung eines Koordinaten-Objektes mit 3 Membervariablen und nachfolgenden Zugriffen darauf liegen. Das wird immerhin (zusammen mit dem Vector-Zugriff) ungefähr 3 000 000 mal pro Sekunde ausgeführt...



  • Ist die entsprechende Stelle klein genug, um sie hier kurz zu erklären? Wie Quellcode beim Übersetzen von C nach C++ dreimal langsamer wird interessiert mich doch irgendwie 🙂



  • hehe, sehr gern. Allerdings ist das nur eine ungefähre Schätzung. Vorher hatte ich eine Funktion, die jeden Frame (soll mal ein kleines Spiel werden) aufgerufen wurde und dabei 256² mal auf ein 256*256 C-Array zugegriffen hat.
    Dabei bekam ich ungefähr 100 FPS.
    Jetzt habe ich alles mögliche geändert, viele Klassen hinzugefügt ect.
    Zum Beispiel eine Terrain-Klasse mit Renderfunktion. Insgesamt bekomme ich damit noch 30 FPS. Die Funktion sieht so aus:

    void Terrain::Render() {
    	CVector3 currVert; //CVector3 ist eine Struktur mit 3 Floats um Koordinaten zu speichern
    	for(int x = 0; x < _koords.width(); ++x)
            { //koords ist das 2dArray (mit der Implementation von oben) mit vector<CVector3> 
    	   glBegin(GL_TRIANGLE_STRIP);
               for(int z = 0; z < _koords.width(); ++z)
               {
    		currVert = _koords(x, z);
    		         glColor3f(currVert._y/(16.0f*_scale),currVert._y/(32.0f*_scale),currVert._y/(64.0f*_scale));
    		glVertex3f(currVert._x, currVert._y, currVert._z);
    
    		currVert = _koords( (x+1)%_koords.width(), z);
    			glColor3f(currVert._y/(16.0f*_scale),currVert._y/(32.0f*_scale),currVert._y/(64.0f*_scale));
    			glVertex3f(currVert._x, currVert._y, currVert._z);
    
    			addPoly_count(2);
            }
    	    glEnd();
        }
    }
    

    Natürlich könnte das jetzt auch aufgrund anderer Änderungen langsamer geworden sein. Dazu habe ich jedoch die 2 Zeilen mit currVert = _koords (bla, bla); entfernt und glVertex und glColor einfach direkt immer 3 mal 0 übergeben. Dabei bekam ich wieder 100 FPS. Das heißt also, dass durch die anderen Änderungen auch etwas Performance verloren geht, denn ich hab ja vorher immerhin noch auf das c-Array zugreifen müssen (und dabei immer noch ein paar einfache Berechnungen ausgeführt), und jetzt ist es ganz ohne was immer noch nur genauso schnell. Aber damit kann ich leben. Deutlich wird ja, dass die Zuweisung, der Vector-Zugriff und die Zugriffe auf die Koordinatenklasse Zeit kosten.
    Noch was: Kompiliere ich mit Release, bekomm ich immerhin schon wieder 76 FPS. Wie viel die Optimierungen vorher bei der C-Version gebracht hätten, weiß ich aber nicht.



  • Dass der vector im Debug-Modus schlecht abschneidet, liegt wahrscheinlich daran, dass da nicht geinlinet wird. Debug-Modus zählt also nicht 😉

    Als ich area hingeschrieben habe, ging es ja erstmal um Speicherplatz-Optimierung. Vielleicht rechnet der Compiler jetzt aber bei jedem Aufruf koords(x, y) erstmal umständlich per Multiplikation aus, wo er zugreifen soll. Eventuell wäre das bei einem vector<vector<T> > bzw. T** schneller, aber die brauchen dafür halt mehr Speicher 😉
    Wenn du aber nicht hier und da mal zufällig koords(x, y) brauchst, sondern alle Elemente der Reihe nach durchgehen willst, könntest du mal probieren, dir im inneren Loop über &_koords(x, y) einen Zeiger auf den ersten CVector3 der Reihe zu holen und dann mit ++zeiger über die Reihe zu wandern. Wenn das wirklich schneller ist, könnte man areas Interface ja anpassen (row_iterator, row_begin() und row_end() hinzufügen z.B. - will nicht mal jemand eine komplette area-Klasse für die FAQ schreiben? 😉 ).
    BTW, ist das Absicht, dass beide Loops bis koords.width() gehen?



  • @Absicht:
    Öhm, abgesehen davon, dass die äußere Schleife vorher nur bis width()-1 ging, ich darin keinen Sinn mehr gesehen habe und die "-1" daher zum Posten des Codes entfernt habe, ja. ( 😕 oder 😕 )
    Und den Rest deines Beitrages muss ich mir nun erstmal ganz langsam schrittweise zu Gemüte führen, und dann werd ich meine Ergebnisse mitteilen (sofern ich das dann auch umsetzen kann 😞 😉 )



  • Hmpf, irgendwie fehlt mir die Vorstellungskraft dazu.
    Ich greife nicht wirklich willkürlich auf _koords(x, y) zu, aber einmal pro Durchlauf der inneren Schleife mit (x, y) und einmal mit (x+1, y). Die Elemente sind aber Spaltenweise im Vector angelegt, dass heißt, wenn ich nicht y in der inneren Schleife, sondern den Zeiger inkrementiere, sollte ich mir (x, y) sparen können, aber (x+1, y) muss ich dennoch aufrufen, weil da ja plötzlich ein Wert in der rechts anliegenden Spalte gesucht wird.
    Vielleicht sollte ich lieber versuchen, den Algorithmus selbst zu ändern, so dass ich nicht immer diesen rechten Nachbarwert brauche...
    Denn 60 Frames pro Sekunde sind eindeutig zu wenig für das was man sieht bei meinem PC, und vorher liefs ja auch schneller.
    Und dann kann ich ja nochmal versuchen, ein paar Compilereinstellungen zu ändern, glaub aber nicht dass es was bringt...


Anmelden zum Antworten