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.
- Használjon takarékosan
- Helyes fordítási beállítások használata
- Est-függvények használata, ha szükséges,
- Igazított adattípusok és műveletek használata
- foglalások megfelelő igazítása
- Operátorok túlterhelésének elkerülése, ha lehetséges,
- denormális
- Kihasználhatja a lebegőpontos lebegőpontos kettősség
- Sablonűrlapok előnyben részesítés
- DirectXMath használata Direct3D
- Kapcsolódó témakörök
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:
Használja a Colors névteret állandókat közvetlenül a ColorRGBA paraméterben az ID3D11DeviceContext::ClearRenderTargetView vagy ID3D10Device::ClearRenderTargetView metódus hívásában. Direct3D 9 esetén az XMCOLOR típusra kell konvertálnia ahhoz, hogy Szín paraméterként használja az IDirect3DDevice9::Clear metódushoz.
A XMFLOAT4/XMVECTOR és XMFLOAT4X4/XMMATRIX típusokkal konstans pufferstruktúrákat állíthat be a HLSL float4 vagy mátrix/float4x4 típus alapján történő referenciaként.
Jegyzet
XMFLOAT4X4/XMMATRIX típusok sor-fő formátumban vannak. Ezért ha a /Zpr fordítókapcsolót (a D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR fordítási jelzőt) használja, vagy kihagyja a row_major kulcsszót, amikor a mátrixtípust HLSL-ben deklarálja, transzponálnia kell a mátrixot, amikor beállítja az állandó pufferbe.
A Direct3D 10.x és a Direct3D 11.x esetén feltételezheti, hogy a Map metódus által visszaadott mutató (például ID3D11DeviceContext::Map) a pData tagban (D3D10_MAPPED_TEXTURE2D.pData, D3D10_MAPPED_TEXTURE3D.pDatavagy D3D11_MAPPED_SUBRESOURCE.pData) 16 bájtos igazítású, ha funkciószintű 10_0 vagy újabb, vagy ha D3D11_USAGE_STAGING erőforrásokat használ.