DirectX 12 Multi-engine: asynchronní shadery v praxi
20.11.2015, Pavel Šantrůček, recenze
Co jsou to asynchronní shadery a k čemu vlastně slouží? Jak zapadají do kontextu DirectX 12? Které grafické karty je podporují, které zase ne a proč? V dnešním článku odpovíme právě na takovéto otázky.
Kapitoly článku:
DirectX 12: Multi-engine
Příchodem DirectX 12 se situace rapidně změnila. To, co přineslo Mantle, adoptoval také Microsoft a veřejnosti představil pod názvem Multi-engine.
V DirectX 12 jsou Command buffery vytvářeny pomocí UMD přímo na každém jádru procesoru a záleží pouze na vývojáři her, kolik těchto jader k vytváření Command bufferů využije. Jakmile je Command buffer hotov, ihned a bez zbytečného otálení, je odeslán na zpracování ke GPU. Tentokrát však ale ne pomocí jediné fronty, ale pomocí hned několika speciálních front.
3D queue
3D queue je sice v celém systému frontou svého druhu jedinou, zato je ale zase nejuniverzálnější. Podobně jako tomu bylo u předchozích verzí DirectX, pomocí ní je možné zasílat příkazy jak grafické a výpočetní, tak také kopírovací.
Comupte queue
Těchto výpočetních front může být využito více, vše záleží pouze na HW možnostech grafické karty. Pomocí těchto výpočetních front je možné zasílat příkazy výpočetní a také kopírovací.
Copy queue
Fronta kopírovací je úzce zaměřena pouze na operace kopírovací a na odesílání jiných příkazů se použít nedá. Kopírovací fronty jsou celkem dvě, ale my se dnes jimi už dále zabývat nebudeme.
Pro nás je důležité to, že pomocí těchto vícero front jsou příkazy na grafickou kartu zasílány paralelně a GPU by je tedy také paralelně mohlo zpracovávat. K tomu je ale potřeba, aby se o každou takovou frontu na straně GPU postaral také jeden samostatný a nezávislý engine. A právě odtud pramení onen výraz Multi-engine.
3D engine se tedy stará o příkazy zaslané pomocí 3D queue, Compute enginy se starají o příkazy z Compute queue a DMA engine zase o příkazy z Copy queue. Příkazy jsou ukládány opět do Command listů, které jsou shromažďovány v příslušném enginu GPU. Každý engine je pak zodpovědný za řádnou exekuci svých Command listů na výpočetních jednotkách grafické karty.
Kýženým výsledkem Multi-engine je tedy souběžná exekuce grafických, výpočetních a kopírovacích příkazů na jednom GPU.
Jak jsou jednotlivé DirectX 12 fronty mapovány na hardware grafické karty a který engine se o ně stará, si můžeme ukázat na grafických kartách architektury GCN.
Z obrázku je patrné, že o 3D queue (grafické příkazy) se stará nám již dobře známý engine GCP (Graphics Command Processor), o Compute queue (výpočetní příkazy) se stará 8 jednotek ACE (Asynchronous Compute Engines) a konečně o Copy queue (kopírovací příkazy) se stará DMA engine. Enginy GCP, ACE i DMA pracují na grafické kartě autonomně a každý tak může odesílat své příkazy k exekuci na výpočetní jednotky grafické karty souběžně s ostatními. V případě GCN jsou pak těmito výpočetními jednotkami CU (Compute Unit).
Multi-engine tedy zajišťuje, že je možné v jednom okamžiku odeslat na výpočetní jednotky GPU úloh více. To však samo o sobě pro souběžnou exekuci těchto úloh nestačí. Máme totiž před sebou ještě jeden velmi zásadní problém. GPU nedisponuje výpočetními jednotkami pro každou úlohu zvlášť, tak, jak je tomu například u vícejádrového CPU, kde můžeme další úlohu spustit na jiném jádru procesoru paralelně. Výpočetní zdroje GPU jsou pouze jedny (ačkoliv jich tam je velké množství) a jak to tedy udělat, aby jedna úloha neokrádala o výpočetní zdroje úlohu druhou?
Odpovědí je Simultánní Multi-threading!