Optimieren der Vertexbuffer
-
Im Prinzip ist mir viel von dem was du da schreibst nicht neu.
Ich wollte aber bloss ne Zahl wissen. Ein Maximum anzugeben ist wahrscheinlich nicht möglich, aber vielleicht hat jmd. schon einen Fall gehabt wo er einen grossen Unterschied gesehen hat der nur durch "umordnen" der Index-Buffer entstanden ist. Dann könnte er/sie/es schreiben "Faktor 2.7 hab ich selbst schon gesehen" - oder sowasNun denkt man sich, ok, was wenn ich riesige vertices habe, dann braucht doch der prefetcher auch vieeel laenger? ja das stimmt, aber dann macht der vertexshader vermutlich auch viel mehr weil er ja mehr daten wollte.
Ich hätte eher an den Fall "mini vertices" gedacht, denn dann kann sich die Adresse von einem "fetch" zum nächsten jedesmal komplett ändern. Mag sein dass ich da noch in Grossvaters Zeiten feststecke, aber gibt's beim Zugriff auf RAMs nicht noch immer Strafe wenn man die "row" und/oder "bank" wechselt?
ein paradebeispiel ist, dass man in shadern statt spruengen an if-else stellen, einfach beide faelle abarbeitet und sich dann am ende nur das richtige ergebniss schnappt -> doppelte arbeit, aber trotzdem schneller, weil einhetliche pipeline
Ja, DAS ist mir von den CPUs her bekannt. Ist ja nicht allzulange her dass wir CPUs mit mörder-langen Pipelines hatten, wo ein branch-prediction-miss ordentlich teuer war. Bzw. es gibt diese CPUs ja immer noch
Deswegen war/ist auch der "conditional move" Befehl bei bestimmten Schleifen eine ganz feine Sache
-
hustbaer schrieb:
Im Prinzip ist mir viel von dem was du da schreibst nicht neu.
Ich wollte aber bloss ne Zahl wissen. Ein Maximum anzugeben ist wahrscheinlich nicht möglich, aber vielleicht hat jmd. schon einen Fall gehabt wo er einen grossen Unterschied gesehen hat der nur durch "umordnen" der Index-Buffer entstanden ist. Dann könnte er/sie/es schreiben "Faktor 2.7 hab ich selbst schon gesehen" - oder sowaswenn du rein vertexshader limitiert bist und hast den worst case von jeweils 3 neuen vertices (was in etwa bei particlen sein kann, da haste ja immer 4 die du danach nie wieder benutzt), gegenueber einem mesh, dass du im zickzack muster abarbeitest, was in etwa 0.5vertices pro dreieck bedeutet, kannst du es ziemlich mit faktor 6 ansetzen... wie gesagt, vertexshader fall.
Nun denkt man sich, ok, was wenn ich riesige vertices habe, dann braucht doch der prefetcher auch vieeel laenger? ja das stimmt, aber dann macht der vertexshader vermutlich auch viel mehr weil er ja mehr daten wollte.
Ich hätte eher an den Fall "mini vertices" gedacht, denn dann kann sich die Adresse von einem "fetch" zum nächsten jedesmal komplett ändern. Mag sein dass ich da noch in Grossvaters Zeiten feststecke, aber gibt's beim Zugriff auf RAMs nicht noch immer Strafe wenn man die "row" und/oder "bank" wechselt?
bei mini vertices ist die wahrscheinlichkeit kleiner dass du zwitchen musst. den penalty gibt es natuerlich immer noch, was eigentlich noch schlimmer geworden ist, weil mit jeder speichergeneration die bandbreite gesteigert wird, die latenz aber gleich bleibt. man ist also sehr auf lokalitaet angewiesen, jedoch arbeiten die gpu hersteller auch dran moeglichst viel in einem rutsch zu lesen (sprich, die cachelines werden laenger und laenger).
ein paradebeispiel ist, dass man in shadern statt spruengen an if-else stellen, einfach beide faelle abarbeitet und sich dann am ende nur das richtige ergebniss schnappt -> doppelte arbeit, aber trotzdem schneller, weil einhetliche pipeline
Ja, DAS ist mir von den CPUs her bekannt. Ist ja nicht allzulange her dass wir CPUs mit mörder-langen Pipelines hatten, wo ein branch-prediction-miss ordentlich teuer war. Bzw. es gibt diese CPUs ja immer noch
Deswegen war/ist auch der "conditional move" Befehl bei bestimmten Schleifen eine ganz feine Sachenaja, nicht ganz. eine cpu haette massig register hazards bei sowas wie
a=a*a; a=a*a; a=a*a; a=a*a; a=a*a;
und wuerde die ganze zeit die pipe stallen, cmove ist, wie du sagst, um die pipe nicht zu flushen.
einer gpu macht diese reihe nichts aus, entsprechend wuerde ein jump auch nicht die pipeline an sich stallen, aber eine gpu als streamprozessor lebt von einem geradelinigen datendurchlauf, generierst du nun unmengen verzweigte logikpfade, teilst du die daten auf die pfade auf. die gpu kann dafuer weder ein sonderlich gutes load balancing betreiben, noch kann sie die entscheidungsfindung parallelisieren.
-
rapso schrieb:
Azrael, il Meraz schrieb:
Wie optimiert man Sortiertechnisch einen Vertex und Indexbuffer am besten?...
Wie kriegt man die beste performance?btw. nicht noetig zu jeder frage einen neuen thread zu starten
Ich komm damit jetzt mal garnicht klar. Ist das normal?
In der Readme steht was von einem Beispiel, welches ich aber nicht finden kann
See the StripTest source code (in function LoadXFileStripped) for an example of using the library.
Vllt brauch ich ja ne Brille. Ich seh da kein StripTest source code und danach suchen klappt auch nicht so wirklich
[edit] grrr - da will man sich bei Irrlicht was abgucken und entdeckt, dass irrlicht Vertexbuffer garnicht verwendet argh xD
-
hustbaer schrieb:
Im Prinzip ist mir viel von dem was du da schreibst nicht neu.
Ich wollte aber bloss ne Zahl wissen. Ein Maximum anzugeben ist wahrscheinlich nicht möglich, aber vielleicht hat jmd. schon einen Fall gehabt wo er einen grossen Unterschied gesehen hat der nur durch "umordnen" der Index-Buffer entstanden ist. Dann könnte er/sie/es schreiben "Faktor 2.7 hab ich selbst schon gesehen" - oder sowasAlso die paar Mal, dass ich das explizit gesehen habe, weil ich ein Model erst ohne Re-indexing importiert habe, und dann mit, hats immer einen merkbaren Boost gegeben. Ich schätze so 1.5x FPS. Wobei, wie schon ausführlich dargelegt, es natürlich immer darauf ankommt, was der limitierende Faktor ist.
@nvtristrip: Hat sich da so viel geändert? Wie ich das seinerzeit benutzt habe, waren das einfach eine handvoll Methoden, die zum Glück ziemlich selbsterklärend waren. Ich glaub "GenerateStrips" heißt die Methode, der man ein Array an Indices füttert und dann eine Liste an Arrays an umgeordneten Indices zurückbekommt (man bekommt deshalb mehrere Arrays zurück, weil das Model eventuell in mehrere Strips zerlegt wird, die nicht miteinander verbunden sind. Gibt auch eine Methode dafür, dass alle Strips in 1 Array zusammengestitcht werden sollen).
-
Ich wollte aber bloss ne Zahl wissen
Du musst hier bedenken, dass ein 3D-Modell ja auch irgendwie "entstanden" ist und die Polygone dementsprechend nicht in voellig zufaelliger Reihenfolge auf dem Objekt liegen - man wird also aeussert selten den Worst-Case sehen.
Bei meinen Versuchen mit hochtesselierten Objekten lag die Cache-Miss-Rate im unoptimierten Zustand durchschnittlich knapp ueber 1 Vertex/Triangle.
-
Hab mal ein paar Artikel zur Optimierung gelesen und bastel mir hier eine Optimierungsfunktion zurecht. (Ja, ich bin mir sicher, dass ich das selber programmieren will :P) jetzt hab ich eindeutig ein Fehler gemacht (Geometrie leicht zerschrottet und die Optimierung stimmt nu auch nicht wirklich, für diese Frage aber irrelevant^^). Ich habe aber immer noch dieselben vertices und indices. Hab einen framedrop von ca 200 fps auf 30 fps. Irgendwie finde ich den framedrop etwas seltsam. Liegt er nur an cache misses?
-
Hab einen framedrop von ca 200 fps auf 30 fps. Liegt er nur an cache misses?
Nein.
-
So leutz. Ich hab diesen Algorithmus hier implementiert : http://www.cs.princeton.edu/gfx/pubs/Sander_2007_>TR/tipsy.pdf
Ich bekomme bei meinem ca. 5000 dreiecken im Model einen performanceverlust von 20%. Ich vermute mal einfach, dass Blender3D (Daher hab ich das Model mit gleichen Indices exportiert) einen internen Superoptimierer hat :D...Und sorry für die leicht ehm... überflüssige frage.
-
Ich vermute mal einfach, dass Blender3D einen internen Superoptimierer hat
Und ich vermute mal einfach, dass Du einen Fehler gemacht hast.
Schmeiss Deinen Indexbuffer mal in einen simulierten Vertex-Cache (zb hier) und poste mal das Verhaeltnis zwischen hit und miss (VCache::add liefert true/false).
-
vor dem optimieralgorithmus:
misses: 6008
hits: 9628
hits per miss: 1.60253nach dem optimieralgorithmus (vcache_size = 16)
misses: 4232
hits: 11404
hits per miss: 2.69471ok, ehm. was muss man noch beachten? "^^
-
mach den test nochmal mit vcache_size = 24 bitte
-
vorher:
misses: 5523
hits: 10113
hits per miss: 1.83107nachher:
misses: 3982
hits: 11654
hits per miss: 2.92667Wieso ist optimierte geometrie bei OpenGL langsamer und bei DirectX schneller?
fps vorher/nachher:
openGL: 310/292Direct3D: 350/388
-
misses: 6008
hits: 9628Bei 6008+9628 Indizes (5212 Triangles, vermutlich weniger als 3000 Vertices) bist Du nicht Vertexdurchsatz-limitiert.
-
Ok, anderes Mesh:
vorher:
misses: 45965
hits: 168307
hits per miss: 3.66163nachher:
misses: 47227
hits: 167045
hits per miss: 3.53707mit vcache_size = 16 krieg ich folgendes ergebnis:
vorher:
misses: 54442
hits: 159830
hits per miss: 2.935784872misses: 49434
hits: 164838
hits per miss: 3.33451Mein Mesh ist eine einfache Kugel. ich denke mal, hier wurden die indices schon bei der erschaffung in einer güngstige reihenfolge gewählt.
Jetzt noch ne frage zu DirectX/OpenGL
Ich habe bei OpenGL eine framerate von ca. 115 fps.
bei DirectX habe ich eine zeit lang auch etwa 120 fps. nach einigen sekunden springen die fps aber plötzlich auf 180-200. Was passiert hier?
-
falls du shader benutzt, kann es sein dass der treiber fertig wurde den zu optimieren und dann ersaetzt er den provisorischen eventuell mit dem 'optimalen'
es kann aber auch an 100 anderen dingen liegen
-
noch fahr ich ohne shader.
Man kann mich ruhig auf 100 andere dinge verweisen wenns unnötig ist sie aufzuzählen. Bin neugierig