Optimalizace kódu pomocí knihovny DirectXMath
Toto téma popisuje aspekty optimalizace a strategie pomocí knihovny DirectXMath.
- Používat přístupové objekty střídmě
- Použít správná nastavení kompilace
- Používat funkce Est v případě potřeby
- použít zarovnané datové typy a operace
- správně zarovnat přidělení
- vyhnout přetížení operátorů, pokud je to možné
- denormals
- využít celočíselnou dualitu
- preferovat formuláře šablon
- použití DirectXMath s direct3D
- související témata
Používejte přístupové objekty střídmě
Vektorové operace používají instrukční sady SIMD a využívají speciální registry. Přístup k jednotlivým komponentám vyžaduje přechod z registrů SIMD na skalární a zpět.
Je-li to možné, je efektivnější inicializovat všechny komponenty XMVECTOR najednou místo použití řady jednotlivých vektorových přístupových objektů.
Použít správná nastavení kompilace
Pro cíle Windows x86 povolte /arch:SSE2. Pro všechny cíle Windows povolte /fp:fast.
Ve výchozím nastavení se kompilace vůči knihovně DirectXMath pro cíle x86 okna provádí s _XM_SSE_INTRINSICS_ definovanými. To znamená, že všechny funkce DirectXMath budou používat pokyny SSE2. Totéž však neplatí pro jiný kód.
Kód mimo DirectXMath se zpracovává pomocí výchozích hodnot kompilátoru. Bez tohoto přepínače může vygenerovaný kód často používat méně efektivní kód x87.
Důrazně doporučujeme vždy používat nejnovější dostupnou verzi kompilátoru.
Použití funkcí Est v případě potřeby
Mnoho funkcí má ekvivalentní odhadní funkci končící na Est. Tyto funkce obchodují s určitou přesností za lepší výkon. Funkce Est jsou vhodné pro nekritické výpočty, kde je možné obětovat přesnost pro rychlost. Přesné množství ztráty přesnosti a zvýšení rychlosti závisí na platformě.
Například funkci XMVector3AngleBetweenNormalsEst lze použít místo funkce XMVector3AngleBetweenNormals.
Použití zarovnaných datových typů a operací
Instrukční sady SIMD ve verzích windows podporujících SSE2 mají obvykle zarovnané a nerovnané verze operací paměti. Použití zarovnaných operací je rychlejší a mělo by se upřednostňovat všude, kde je to možné.
Knihovna DirectXMath poskytuje přístup zarovnané a nezarovnané funkce prostřednictvím typů, struktur a funkcí variant. Tyto varianty jsou označené "A" na konci názvu.
Existují například nerovnané XMFLOAT4X4 struktury a zarovnané XMFLOAT4X4A struktury, které používají XMStoreFloat4 a funkce XMStoreFloat4A.
Správně zarovnat přidělení
Zarovnané verze SSE vnitřních objektů, které jsou podkladovou knihovnou DirectXMath, jsou rychlejší než nerovnané.
Z tohoto důvodu operace DirectXMath používající XMVECTOR a XMMATRIX objekty předpokládají, že tyto objekty jsou zarovnané na 16bají. To je automatické pro přidělování na základě zásobníku, pokud je kód zkompilován proti knihovně DirectXMath pomocí doporučeného systému Windows (viz Použít správné nastavení kompilace) nastavení kompilátoru. Je však důležité zajistit, aby přidělení haldy obsahující XMVECTOR a XMMATRIX objekty nebo přetypování na tyto typy splňovaly tyto požadavky na zarovnání.
I když jsou 64bitové přidělení paměti Windows zarovnané na 16 bajtů, ve výchozím nastavení je přidělena 32bitová verze paměti Systému Windows pouze 8 bajtů zarovnaná. Informace o řízení zarovnání paměti naleznete v tématu _aligned_malloc.
Pokud používáte zarovnané typy DirectXMath se standardní knihovnou šablon (STL), budete muset poskytnout vlastní alokátor, který zajistí zarovnání 16 bajtů. Podívejte se na blog týmu Visual C++ příklad psaní vlastního alokátoru (místo malloc/free budete chtít použít _aligned_malloc a _aligned_free ve své implementaci).
Poznámka
Některé šablony STL upravují zarovnání zadaného typu. Například make_shared<> přidá některé interní informace o sledování, které mohou nebo nemusí respektovat zarovnání zadaného typu uživatele, což vede k nerovnaným datovým členům. V takovém případě musíte místo zarovnaných typů použít nerovnané typy. Pokud odvozujete z existujících tříd, včetně mnoha objektů prostředí Windows Runtime, můžete také upravit zarovnání třídy nebo struktury.
Vyhněte se přetížení operátorů, pokud je to možné
Jako funkce pohodlí má řada typů, jako je XMVECTOR a XMMATRIX, přetížení operátorů pro běžné aritmetické operace. Přetížení těchto operátorů mají tendenci vytvářet mnoho dočasných objektů. Doporučujeme, abyste se těmto přetížením operátorů vyhnuli v kódu citlivém na výkon.
Denormals
Pro podporu výpočtů v blízkosti 0 zahrnuje standard float-point IEEE 754 podporu pro postupné podtečení. Postupné podtečení se implementuje pomocí denormalizovaných hodnot a při zpracování denormalizovaných hodnot je mnoho implementací hardwaru pomalé. Optimalizace, kterou je potřeba vzít v úvahu, je zakázat zpracování denormálů pro vektorové operace používané DirectXMath.
Změna zpracování denormalů se provádí pomocí rutiny _controlfp_s na základě předprocesu a může vést k vylepšení výkonu. Pomocí tohoto kódu můžete změnit zpracování denormalů:
#include <float.h>;
unsigned int control_word;
_controlfp_s( &control_word, _DN_FLUSH, _MCW_DN );
Poznámka
V 64bitových verzích Windows se pokyny SSE používají pro všechny výpočty, nejen pro vektorové operace. Změna denormálního zpracování ovlivňuje všechny výpočty s plovoucí desetinou čárkou v programu, nejen operace vektoru používané directXMath.
Využijte výhod duality s plovoucí desetinou čárkou celé číslo.
DirectXMath podporuje vektory 4 s plovoucí desetinnou čárkou s jednoduchou přesností nebo čtyřmi 32bitovými (podepsanými nebo nepodepsanými) hodnotami.
Vzhledem k tomu, že instrukční sady používané k implementaci knihovny DirectXMath mají možnost pracovat se stejnými daty jako s několika různými typy, lze dosáhnout stejných vektorů jako s plovoucí desetinou čárkou a celočíselnou optimalizací. Tyto optimalizace můžete získat pomocí inicializačních rutin celočíselné vektorové inicializace a bitových operátorů pro manipulaci s hodnotami s plovoucí desetinou čárkou.
Binární formát čísel s plovoucí desetinnou čárkou s jednoduchou přesností používaný knihovnou DirectXMath zcela odpovídá standardu IEEE 754:
SIGN EXPONENT MANTISSA
X XXXXXXXX XXXXXXXXXXXXXXXXXXXXXXX
1 bit 8 bits 23 bits
Při práci s jedním číslem s plovoucí desetinnou čárkou IEEE 754 je důležité mít na paměti, že některé reprezentace mají zvláštní význam (to znamená, že neodpovídají předchozímu popisu). Mezi příklady patří:
- Kladná nula je 0
- Záporná nula je 0x80000000
- Q_NAN je 07FC0000
- +INF je 0x7F800000
- -INF je 0xFF800000
Preferovat formuláře šablon
Formulář šablony existuje pro XMVectorSwizzle, XMVectorPermute, XMVectorInsert, XMVectorShiftLeftLeft, XMVectorRotateLefta XMVectorRotateRight. Použití těchto metod místo formuláře obecné funkce umožňuje kompilátoru vytvářet mnohem efektivnější implementace. U SSE se často sbalí na jednu nebo dvě _mm_shuffle_ps hodnoty. Pro ARM-NEON může šablona XMVectorSwizzle využít řadu speciálních případů, nikoli obecnější vtBL swizzle/permute.
Použití DirectXMath s Direct3D
Běžným použitím DirectXMath je provádění grafických výpočtů pro použití s Direct3D. S Direct3D 10.x a Direct3D 11.x můžete knihovnu DirectXMath používat těmito přímými způsoby:
Použijte konstanty oboru názvů Colors přímo v parametru ColorRGBA volání metody ID3D11DeviceContext::ClearRenderTargetView nebo ID3D10Device::ClearRenderTargetView metoda. V případě Direct3D 9 je nutné převést na typ XMCOLOR použít ho jako parametr Color ve volání IDirect3DDevice9::Clear metody.
Pomocí typů XMFLOAT4/XMVECTOR a XMFLOAT4X4/XMMATRIX nastavte konstantní vyrovnávací struktury pro odkazování hlSL float4 nebo matici/float4x4.
Poznámka
XMFLOAT4X4/typy XMMATRIX jsou ve formátu hlavního řádku. Proto pokud použijete přepínač kompilátoru /Zpr (příznak kompilace D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR) nebo vynecháte klíčové slovo row_major při deklaraci typu matice v HLSL, musíte tuto matici transponovat při nastavení do konstantní vyrovnávací paměti.
U Direct3D 10.x a Direct3D 11.x můžete předpokládat, že ukazatel vrácený metodou Map (například ID3D11DeviceContext::Map) v členu pData (D3D10_MAPPED_TEXTURE2D.pData, D3D10_MAPPED_TEXTURE3D.pDatanebo D3D11_MAPPED_SUBRESOURCE.pData) je zarovnaný na úrovni funkce 10_0 nebo vyšší nebo kdykoli použijete D3D11_USAGE_STAGING prostředky.
Související témata
-
Průvodce programováním DirectXMath