Megosztás a következőn keresztül:


Kódoptimalizálás a DirectXMath-kódtárral

Ez a témakör a DirectXMath-kódtárral kapcsolatos optimalizálási szempontokat és stratégiákat ismerteti.

Tartozék takarékos használata

A vektoralapú műveletek a SIMD utasításkészleteket használják, és speciális regisztereket használnak. Az egyes összetevők eléréséhez a SIMD-regiszterekről a skalárisakra kell áttérni, és újra vissza kell őket visszahozni.

Ha lehetséges, hatékonyabb inicializálni egy XMVECTOR összes összetevőjét egyszerre, ahelyett, hogy egyedi vektorkiegészítőket használnál.

A megfelelő fordítási beállítások használata

Windows x86-példányok esetén engedélyezze az /arch:SSE2 elemet. Minden Windows-célhoz engedélyezze a /fp:fast parancsot.

Alapértelmezés szerint az x86-os windowsos DirectXMath-kódtárra való fordítás _XM_SSE_INTRINSICS_ van megadva. Ez azt jelenti, hogy minden DirectXMath-funkció az SSE2 utasításokat fogja használni. Ugyanez azonban nem igaz más kódokra.

A DirectXMath-on kívüli kódokat a fordító alapértelmezései alapján kezeli a rendszer. E kapcsoló nélkül a létrehozott kód gyakran a kevésbé hatékony x87-kódot használja.

Javasoljuk, hogy mindig a fordító legújabb elérhető verzióját használja.

Est-függvények használata, ha szükséges

Számos függvény azonos becslési függvénysel rendelkezik, amely Est-ben végződik. Ezek a függvények némi pontossággal kereskednek a jobb teljesítmény érdekében. Az Est-függvények olyan nem kritikus számításokhoz használhatók, ahol a pontosság feláldozható a sebességért. Az elveszett pontosság és a sebesség növelése pontosan platformfüggő.

Az XMVector3AngleBetweenNormalsEstfüggvény például az XMVector3AngleBetweenNormals függvény helyett használható.

Igazított adattípusok és műveletek használata

Az SSE2-t támogató Windows-verziók SIMD-utasításkészletei általában a memóriaműveletek összehangolt és el nem elosztva verzióival rendelkeznek. Az igazított műveletek használata gyorsabb, és ahol csak lehetséges, előnyben kell részesíteni.

A DirectXMath-kódtár a variánsvektortípusokon, szerkezeteken és függvényeken keresztül hozzáférést biztosít a hozzáigazított és el nem felosztott funkciókhoz. Ezeket a változatokat a név végén egy "A" jelöli.

Létezik például egy el nem felosztásos XMFLOAT4X4 és egy igazított XMFLOAT4X4A struktúra, amelyet az XMStoreFloat4, illetve az XMStoreFloat4A függvények használnak.

Foglalások megfelelő igazítása

Az SSE DirectXMath-kódtár alapjául szolgáló belső verziók gyorsabbak, mint a nem elaltatottak.

Emiatt az XMVECTOR és XMMATRIX objektumokat használó DirectXMath-műveletek feltételezik, hogy ezek az objektumok 16 bájtos igazítással vannak igazítva. Ez automatikusan történik a veremalapú foglalások esetében, ha a kód a DirectXMath-kódtárra van lefordítva az ajánlott Windows használatával (lásd Helyes fordítási beállítások használata) fordítóbeállításokat. Fontos azonban biztosítani, hogy az XMVECTOR és XMMATRIX objektumokat vagy ezekre a típusokat tartalmazó halomfoglalás megfeleljen ezeknek az igazítási követelményeknek.

Míg a 64 bites Windows-memóriafoglalások 16 bájtos igazítással vannak elosztva, alapértelmezés szerint a lefoglalt Windows-memória 32 bites verzióiban csak 8 bájt van igazítva. A memória igazításának szabályozásáról további információt a _aligned_malloccímű témakörben talál.

Ha igazított DirectXMath-típusokat használ a standard sablontárhoz (STL), egy egyéni kiosztót kell megadnia, amely biztosítja a 16 bájtos igazítást. Tekintse meg a Visual C++ csapat blog egy egyéni kiosztó írására vonatkozó példát (malloc/free helyett _aligned_malloc és _aligned_free szeretne használni a megvalósításban).

Jegyzet

Egyes STL-sablonok módosítják a megadott típus igazítását. Például make_shared<> olyan belső nyomkövetési információkat ad hozzá, amelyek esetleg nem tartják tiszteletben a megadott felhasználói típus igazítását, ami nem elalkosított adattagokat eredményez. Ebben az esetben az igazított típusok helyett nem elalkulált típusokat kell használnia. Ha meglévő osztályokból származik, beleértve számos Windows futtatókörnyezeti objektumot is, módosíthatja egy osztály vagy struktúra igazítását is.

 

Ha lehetséges, kerülje az operátorok túlterhelését

Kényelmi funkcióként számos típus, például XMVECTOR és XMMATRIX operátorok túlterhelése van a gyakori aritmetikai műveletekhez. Az ilyen operátorok túlterhelései általában számos ideiglenes objektumot hoznak létre. Javasoljuk, hogy kerülje ezeket az operátorok túlterhelését a teljesítményérzékeny kódban.

Denormálisok

A 0-hoz közeli számítások támogatásához az IEEE 754 lebegőpontos szabvány támogatja a fokozatos alulcsordulást. A fokozatos alulcsordulás denormalizált értékek használatával valósul meg, és sok hardveres implementáció lassú a denormális értékek kezelésekor. Az optimalizálást érdemes megfontolni a DirectXMath által használt vektorműveletek denormális kezelésének letiltása.

A denormálisok kezelésének módosítása a _controlfp_s rutin előszálas használatával történik, és teljesítménybeli javulást eredményezhet. Ezzel a kóddal módosíthatja a denormálisok kezelését:

  #include <float.h>;
    unsigned int control_word;
    _controlfp_s( &control_word, _DN_FLUSH, _MCW_DN );

Jegyzet

A Windows 64 bites verzióiban SSE utasításokat használunk az összes számításhoz, nem csak a vektorműveletekhez. A denormális kezelés módosítása a program összes lebegőpontos számítását érinti, nem csak a DirectXMath által használt vektorműveleteket.

 

Használja ki a lebegőpontos lebegőpontos kettősség egész számának előnyeit

A DirectXMath 4 egypontos lebegőpontos vagy négy 32 bites (aláírt vagy aláíratlan) vektort támogat.

Mivel a DirectXMath-kódtár implementálásához használt utasításkészletek képesek ugyanazokat az adatokat több különböző típussal kezelni, ugyanazt a vektort például lebegőpontos és egész adatoptimalizációkkal lehet kezelni. Ezeket az optimalizálásokat az egész számvektor inicializálási rutinjaival és bitszintű operátorokkal érheti el a lebegőpontos értékek manipulálásához.

A DirectXMath-kódtár által használt egy pontosságú lebegőpontos számok bináris formátuma teljesen megfelel az IEEE 754 szabványnak:

     SIGN    EXPONENT   MANTISSA
     X       XXXXXXXX   XXXXXXXXXXXXXXXXXXXXXXX
     1 bit   8 bits     23 bits

Az IEEE 754 egyetlen pontosságú lebegőpontos szám használatakor fontos szem előtt tartani, hogy egyes reprezentációk különleges jelentéssel rendelkeznek (azaz nem felelnek meg az előző leírásnak). Ilyenek például a következők:

  • A pozitív nulla 0
  • A negatív nulla 0x80000000
  • Q_NAN 07FC0000
  • A +INF 0x7F800000
  • -AZ INF 0xFF800000

Sablonűrlapok előnyben részesítve

Sablonűrlap létezik XMVectorSwizzle, XMVectorPermute, XMVectorInsert, XMVectorShiftLeft, XMVectorRotateLeftés XMVectorRotateRight. Az általános függvényűrlap helyett ezek használatával a fordító sokkal hatékonyabb implementációkat hozhat létre. Az SSEesetében ez gyakran összecsukható egy vagy két _mm_shuffle_ps értékre. Az ARM-NEON esetében az XMVectorSwizzle sablon számos speciális esetet képes használni az általánosabb VTBL-swizzle/permute helyett.

A DirectXMath használata a Direct3D-vel

A DirectXMath gyakran használ grafikus számításokat a Direct3D-vel való használathoz. A Direct3D 10.x és a Direct3D 11.x használatával a DirectXMath kódtárat az alábbi közvetlen módokon használhatja:

DirectXMath programozási útmutató