Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Už není nutné uvažovat o prostředcích jako o těch, které se vytvářejí v paměti videa nebo v systémové paměti. Nebo jestli má modul runtime spravovat paměť. Díky architektuře nového modelu ovladače WDDM (Windows Display Driver Model) nyní aplikace vytvářejí prostředky Direct3D 10 s různými příznaky použití, které naznačují, jak aplikace hodlá používat data těchto prostředků. Nový model ovladače virtualizuje paměť používanou prostředky; Pak se stane zodpovědností operačního systému, ovladače nebo správce paměti umístit prostředky do nejvýkonnější oblasti paměti, pokud je to možné vzhledem k očekávanému využití.
Výchozím případem je dostupnost prostředků pro GPU. Samozřejmě, že existují časy, kdy data prostředků musí být k dispozici pro procesor. Kopírování dat o prostředcích kolem, aby k němu příslušný procesor mohl přistupovat, aniž by to mělo vliv na výkon, vyžaduje určité znalosti o tom, jak fungují metody rozhraní API.
Kopírování zdrojových dat
Prostředky se vytvářejí v paměti, když Direct3D spustí volání Create. Mohou být vytvořeny v paměti videa, systémové paměti nebo jiném druhu paměti. Vzhledem k tomu, že model ovladače WDDM virtualizuje tuto paměť, aplikace už nemusí sledovat, v jakém typu paměťových prostředků jsou vytvořeny.
V ideálním případě by se všechny prostředky nacházely v paměti videa, aby k nim gpu mohl mít okamžitý přístup. Někdy je však nutné, aby procesor načetl data o prostředcích nebo aby GPU získal přístup k datům prostředků, která byla zapsána procesorem. Direct3D 10 zpracovává tyto různé scénáře tím, že požaduje, aby aplikace specifikovala využití, a následně nabízí několik metod pro kopírování dat prostředků v případě potřeby.
V závislosti na tom, jak byl prostředek vytvořen, není vždy možné získat přímý přístup k podkladovým datům. To může znamenat, že data prostředků musí být zkopírována ze zdrojového prostředku do jiného prostředku, který je přístupný příslušným procesorem. Pokud jde o Direct3D 10, k výchozím prostředkům je možné přistupovat přímo pomocí GPU, dynamických a přípravných prostředků přímo pomocí procesoru.
Po vytvoření prostředku není možné změnit jeho využití. Místo toho zkopírujte obsah jednoho prostředku do jiného prostředku, který byl vytvořen s jiným využitím. Direct3D 10 poskytuje tuto funkci třemi různými metodami. První dvě metody( ID3D10Device::CopyResource a ID3D10Device::CopySubresourceRegion) jsou určené ke kopírování dat prostředků z jednoho prostředku do druhého. Třetí metoda (ID3D10Device::UpdateSubresource) je určená ke kopírování dat z paměti do prostředku.
Existují dva hlavní druhy prostředků: mapovatelné a nemapovatelné. Prostředky vytvořené s dynamickým nebo přípravným využitím jsou mapovatelné, zatímco prostředky vytvořené s výchozím nebo neměnným využitím nejsou mapovatelné.
Kopírování dat mezi nemapovatelnými prostředky je velmi rychlé, protože se jedná o nejběžnější případ a byl optimalizován tak, aby dobře fungoval. Vzhledem k tomu, že tyto prostředky nejsou přímo přístupné procesorem, jsou optimalizované tak, aby s nimi GPU mohl rychle manipulovat.
Kopírování dat mezi mapovatelnými prostředky je problematické, protože výkon bude záviset na využití, se kterým byl prostředek vytvořen. Gpu může například číst dynamický prostředek poměrně rychle, ale nemůže do něj zapisovat a GPU nemůže číst ani zapisovat přímo do připravovaných zdrojů.
Aplikace, které chtějí kopírovat data z prostředku s výchozím využitím do prostředku s přípravným využitím (aby procesor mohl číst data – tj. problém se zpětným čtením GPU) to musí provést opatrně. Další podrobnosti o tomto posledním případu najdete v tématu Přístup k datům prostředků.
Přístup k údajům o prostředcích
Přístup k prostředku vyžaduje mapování prostředku; mapování v podstatě znamená, že se aplikace snaží poskytnout procesoru přístup k paměti. Proces mapování prostředku tak, aby procesor měl přístup k podkladové paměti, může způsobit určité kritické body výkonu a z tohoto důvodu je potřeba vzít v úvahu, jak a kdy provést tuto úlohu.
Výkon může zcela zastavit, pokud se aplikace pokusí namapovat prostředek ve špatnou dobu. Pokud se aplikace pokusí získat přístup k výsledkům operace před dokončením této operace, dojde k zpomalení kanálu.
Provedení operace mapování v nesprávné době může potenciálně způsobit závažný pokles výkonu vynucením GPU a synchronizace procesoru mezi sebou. K této synchronizaci dojde, pokud aplikace chce získat přístup k prostředku před tím, než GPU dokončí kopírování do prostředku, který procesor může mapovat.
Procesor může číst pouze z prostředků vytvořených pomocí příznaku D3D10_USAGE_STAGING. Vzhledem k tomu, že prostředky vytvořené pomocí tohoto příznaku nelze nastavit jako výstupy kanálu, pokud procesor chce číst data v prostředku vygenerovaném GPU, musí se data zkopírovat do prostředku vytvořeného pomocí pracovního příznaku. Aplikace to může provést pomocí ID3D10Device::CopyResource nebo ID3D10Device::CopySubresourceRegion metody kopírování obsahu jednoho prostředku do druhého. Aplikace pak může získat přístup k tomuto prostředku zavoláním příslušné metody Map. Pokud už přístup k prostředku nepotřebujete, aplikace by měla zavolat odpovídající metodu Unmap. Například ID3D10Texture2D::Map a ID3D10Texture2D::Unmap. Různé metody mapování vrací určité hodnoty v závislosti na vstupních příznakech. Podrobnosti najdete v části Poznámky k mapám.
Poznámka
Když aplikace volá metodu Map, obdrží ukazatel na data prostředků pro přístup. Modul runtime zajišťuje, že ukazatel má specifické zarovnání v závislosti na úrovni funkce. U D3D_FEATURE_LEVEL_10_0 a vyšší je ukazatel zarovnaný na 16 bajtů. Pro nižší než D3D_FEATURE_LEVEL_10_0je ukazatel zarovnaný na 4 bajty. Zarovnání 16 bajtů umožňuje aplikaci provádět operace SSE-optimalizované operace s daty nativně bez rekonignace nebo kopírování.
Důležité informace o výkonu
Je nejlepší si představit počítač jako počítač běžící jako paralelní architekturu se dvěma hlavními typy procesorů: jeden nebo více procesorů a jeden nebo více GPU. Stejně jako v jakékoli paralelní architektuře je nejlepšího výkonu dosaženo, když je každý procesor naplánován s dostatečnými úlohami, aby se zabránilo nečinnosti a když práce jednoho procesoru nečeká na práci jiného.
Nejhorší scénář paralelismu GPU/CPU nastává, když je potřeba donutit jeden procesor, aby čekal na výsledky práce provedené jiným procesorem. Direct3D 10 se pokusí tyto náklady odebrat tím, že ID3D10Device::CopyResource a ID3D10Device::CopySubresourceRegion metody asynchronní; kopie nemusí být nutně spuštěna v době, kdy metoda vrátí. Výhodou je, že aplikace neplatí náklady na výkon při skutečném kopírování dat, dokud procesor nepřistoupí k datům, což nastane při zavolání Map. Pokud je metoda Map volána po zkopírování dat, nedojde ke ztrátě výkonu. Na druhou stranu, pokud je metoda Map volána před zkopírováním dat, dojde k zárůstu latence potrubí.
Asynchronní volání v Direct3D 10 (které tvoří většinu metod, a zejména volání vykreslování) jsou uložena v tom, co se nazývá příkazový buffer. Tato vyrovnávací paměť je interní pro grafický ovladač a používá se k dávkovému volání základního hardwaru, aby nákladný přechod z uživatelského režimu do režimu jádra v systému Microsoft Windows probíhal co nej zřídka.
Příkazový buffer se vyprázdní, což způsobí přepnutí mezi uživatelským a jádrovým režimem v jedné ze čtyř následujících situací.
- se nazývá.
- ID3D10Device::Flush se volá.
- Příkazový buffer je plný; jeho velikost je dynamická a je řízena operačním systémem a grafickým ovladačem.
- Procesor vyžaduje přístup k výsledkům příkazu, který čeká na spuštění v vyrovnávací paměti příkazu.
Ze čtyř výše uvedených situací je číslo čtyři nejdůležitější pro výkon. Pokud aplikace vydá ID3D10Device::CopyResource nebo ID3D10Device::CopySubresourceRegion volání, bude toto volání zařazeno do vyrovnávací paměti příkazu. Pokud se aplikace poté pokusí namapovat přípravný prostředek, který byl cílem volání kopírování před vypláchnutím příkazové vyrovnávací paměti, dojde k zastavení kanálu, protože je třeba nejen provést volání metody kopírování, ale také všechny ostatní příkazy v příkazové vyrovnávací paměti. To způsobí synchronizaci GPU a procesoru, protože procesor bude čekat na přístup k přípravnému prostředku, zatímco GPU vyprázdní vyrovnávací paměť příkazů a nakonec naplní prostředek, který procesor potřebuje. Jakmile GPU dokončí kopírování, procesor začne přistupovat k přechodovému prostředku, ale během této doby bude GPU nečinné.
Pokud to uděláte často za běhu, výrazně snížíte výkon. Z tohoto důvodu by se mělo mapování prostředků vytvořených s výchozím využitím provádět opatrně. Aplikace musí počkat dostatečně dlouho, než se vyrovnávací paměť příkazu vyprázdní, a proto musí všechny tyto příkazy dokončit, než se pokusí namapovat odpovídající přípravný prostředek. Jak dlouho má aplikace čekat? Alespoň dva snímky, protože to umožní maximální využití paralelismu mezi CPU a GPU. GPU funguje tak, že zatímco aplikace zpracovává rámec N odesláním volání do vyrovnávací paměti příkazů, GPU je zaneprázdněn prováděním volání z předchozího rámce N-1.
Takže pokud aplikace chce mapovat prostředek, který pochází z paměti videa a volá ID3D10Device::CopyResource nebo ID3D10Device::CopySubresourceRegion v rámci N, toto volání se ve skutečnosti začne spouštět v rámci N+1, když aplikace odesílá volání pro další snímek. Kopie by měla být dokončena, když aplikace zpracovává rámec N+2.
| Rám | Stav GPU/CPU |
|---|---|
| N |
|
| N+1 |
|
| N+2 |
|
| N+3 |
|
| N+4 | ... |
Související témata