Sdílet prostřednictvím


Optimalizace kódu pomocí knihovny DirectXMath

Toto téma popisuje aspekty optimalizace a strategie pomocí knihovny DirectXMath.

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:

Průvodce programováním DirectXMath