PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : D3D Vertexbuffer - Performance-Falle?


zeckensack
2003-08-24, 20:02:20
Ich habe mich jetzt ein wenig mit VBOs unter OpenGL befasst, die ja ein ähnliches Nutzungsprofil aufweisen wie D3D's Vertexbuffer.

Nun ist mir aufgefallen, daß es unzählige Nutzungsmöglichkeiten gibt, die schlechter sind als Vertex Arrays im System-Speicher. Es ist beispielsweise so gut wie unmöglich, VBOs für dynamische Daten (ändern, einmal rendern, wiederholen) zu benutzen, egal ob man die korrekten usage hints benutzt, und egal ob man den Transfer von der API machen lässt, oder den Speicher "lockt". Ich erreiche bisher immer weniger Performance, als würde ich die Daten einfach im System-Speicher parken.

Das einzige was wirklich schneller wird, ist statische Geometrie.
Ist das bei D3D auch so? Weil, irgendwie denke ich könnte das glatt ein Architekturproblem sein. HW-Buffer können theoretisch System-Bandbreite sparen (mindestens ein Kopiervorgang entfällt), und bieten natürlich dem Chip eine höhere Lesebandbreite.

Nur auf der anderen Seite stehen üble Synchronisationsprobleme (wenn aus einem Puffer gelesen wird, während er geändert werden soll) und der AGP, der IMO ziemlich stark auf DMA ausgelegt ist.

Ist das ein Treiberproblem? Vielleicht, aber irgendwie kann ich mir nicht so recht vorstellen, daß ATI und NV, die sehr ähnliche Funktionalität schließlich auch für D3D zur Verfügung stellen, auf einmal damit Probleme haben sollten.

Hmmm ...

Demirug
2003-08-24, 20:08:20
Hast du mal ein paar Daten wie Anzahl von Verticen pro Batch usw? Ich habe bisher nicht wirklich gross gemessen weil ich noch zuviel debugcode im System habe.

zeckensack
2003-08-24, 20:25:20
Original geschrieben von Demirug
Hast du mal ein paar Daten wie Anzahl von Verticen pro Batch usw? Ich habe bisher nicht wirklich gross gemessen weil ich noch zuviel debugcode im System habe. 300k Vertices = 4.8MB pro Batch (Minimalausstattung: 3x float für Position, 4x ubyte für Farbe).

Transferrate aus dem System-RAM:
300MB/s (Update der Daten ist herausgerechnet). Beide IHVs. Keine Geometrie-Limitierung, 100%ig transferlimitiert.

Transferrate in den HW-Buffer:
ATI/Lock 192MB/s
NV/Lock 2GB/s *
ATI/API-gesteuert 370MB/s
NV/API-gesteuert 470MB/s

*AGP-Speicher. Der Deto benutzt bei Locks eine 'Staging area', der Meßwert ist daher im Grunde wertlos.


Angenommen, die 470MB/s sind echt (Transfer auf die Karte, und nicht in AGP-Speicher), dann ist das zwar, ermutigend, reicht aber nicht aus, um die Synchronisationsprobleme auszugleichen.

Zum Vergleich, dieses Batchlein kann ich aus dem System-Speicher mit 60fps rendern. Mit dem VBO-Update/dann rendern-Prozess komme ich auf 40fps. Trotz meßtechnisch besserer Transferrate. Bei ATI ist's noch eindeutiger.

Demirug
2003-08-24, 23:21:44
So ich habe dann mal ein bischen gemesen mit meiner schäbigen 5200er hier in dem Rechner.

Bei DirectX gibt es ja im Prinzip 5 Möglichkeiten einen VB anzulegen.

1. Default-Statisch: Der Treiber entscheidet wo die daten hinkommen vorzugsweise in den Grafikspeicher
2. Managed-Statisch: Ist im Prinzip ähnlich wie Default-Statisch nur das DX noch eine Kopie der Daten hält und bei Bedarf das ein und auslagern aus dem vom Treiber dafür bestimmten Speicher übernimmt
3. Default-Dynamisch: Ein Spezial VB für daten die sich jeden Frame (auch mehrmals) ändern können wobei der Treiber die Wahl hat wo der Speicher den nun liegen soll (normalerweise im AGP Bereich das Hauptspeichers).
4. Systemram-Statisch. Wie 1 nur fest im normalen RAM.
5. Systemram-Dynamisch. Wie 3 nur fest im normalen RAM.

Ich habe jetzt mal die Varianten 1 sowie 3-5 gemessen jeweils mit 16 Byte Verticen und 32 Byte Verticen


16 Byte 32 Byte
1. 50 FPS 50 FPS
3. 38 FPS 25 FPS
4. 44 FPS 38 FPS
5. 41 FPS 10 FPS


Die 50 FPS müssen das Limit des Trisetup sein weil eine reduktion der Drawcalls bei gleicher Dreiecksanzahl nichts mehr bringt.

PS: Ich Idiot habe mal wieder mit der Bebug Runtime gemessen es könnte also teilweise noch etwas mehr sein aber das dürfte dann alles betreffen.