So ganz den Durchblick habe ich da auch noch nicht, aber da sehe ich jetzt wenig neus architekturspezifisches Optimierungspotential, wohl aber welches, von dem
alle Architekturen mehr oder weniger automatisch profitieren.
Da muss man aber auch unterscheiden, von welcher Art Speicher wir reden:
- Texturspeicher. Texturen liegen ja in der Regel nicht linear im Speicher, sondern eben so, dass die GPU da möglichst effizient drauf zugreifen kann - in der Regel
tiled für bessere Cache-Effizienz beim Lesen.
Bei Vulkan kannst du Tiling explizit aktivieren und gibst nen Verwendungszweck an, der Treiber wählt dann das beste Layout aus - bei den älteren APIs muss der Treiber raten, was du vorhast. Da aber fast alle Texturen ausschließlich zum Sampling in Shadern verwendet werden, wird das nicht viel ändern. Auch daran, dass AMD zu blöd ist, 3D-Texturen richtig zu tilen (finde jetzt gerade den Artikel nicht wieder, aber das ist offenbar zumindest bei den älteren GCN-Karten ein echtes Problem), wird man nichts ändern können.
- Linearer Speicher. Hier musst du jetzt entscheiden, ob du Speicher willst, der
o nur von der GPU benutzt werden kann
o sowohl von GPU als auch CPU mit
expliziten Synchronisationsprimitiven benutzt werden kann, oder
o voll kohärent von CPU und GPU benutzt werden kann.
Außerdem kannst du ein paar Eigenschaften verschiedener Speicherblöcke abfragen, wirklich Einfluss auf den Allokator kann man aber wohl nicht nehmen. Zumal der ja auch noch vom Treiber implementiert wird.
Der zweite Punkt wird glaube ich in der Regel so umgesetzt, dass GPU und CPU sich in ihren eigenen Addressräumen Speicher reservieren und die GPU dann bei Bedarf per DMA auf die Daten im normalen Systemspeicher zugreift. Sinn des Ganzen ist halt einfach, dass du Daten überschreiben kannst und dann
ein Mal nen Commit ausführst. Der kohärente Modus dürfte dagegen auf HSA-fähigen APUs schnell sein, auf Desktop-Systemen mit dedizierter GPU dagegen eher langsam.
Das entspricht quasi 1:1 den entsprechenden Mapping-Flags der
GL_ARB_buffer_storage-Extension, aber in D3D11 ist das meines Wissens nicht möglich und das Mappen eines Buffers in den CPU-Addressraum ist da damit nicht nur generell langsam, sondern
erst recht langsam, wenn der Treiber nicht richtig errät, was deine Anwendung macht. Andererseits ist da auch kein gleichzeitiger Zugriff von GPU und CPU möglich, wobei der Punkt für Spiele weitaus weniger interessant sein dürfte als für Compute-intensive Anwendungen.
Weiterer Vulkan-Vorteil ist das Memory Model. Bei D3D11 sind AFAIK
alle Operationen konsistent, bei OpenGL muss man nur wenige Operationen von Hand synchronisieren, bei Vulkan (soweit ich die Specs richtig verstehe)
alle Operationen, die irgendwie voneinander abhängig sind.
Ansonsten gelten da aber dieselben Regeln wie sonst auch - lieber einen großen Puffer reservieren als zehn kleine und nicht quer über den ganzen Speicher verteilt lesen und schreiben. Aber auch das galt es schon bei den alten APIs zu beachten, denn die Möglichkeit, GPU-Speicher für nahezu beliebige Zwecke zu reservieren und sich dann damit auszutoben, ist nicht neu.