共用方式為


DirectXMath 連結庫的程式代碼優化

本主題描述 DirectXMath 連結庫的優化考慮和策略。

謹慎使用存取子

以向量為基礎的作業會使用 SIMD 指令集,並使用這些特殊快取器。 存取個別元件需要從 SIMD 快取器移至純量緩存器,然後再返回一次。

可能的話,一次初始化 XMVECTOR 的所有元件會更有效率,而不是使用一系列的個別向量存取子。

使用正確的編譯設定

針對 Windows x86 目標,啟用 /arch:SSE2。 針對所有 Windows 目標,啟用 /fp:fast。

根據預設,針對 Window x86 目標的 DirectXMath 連結庫進行編譯時,會定義_XM_SSE_INTRINSICS_。 這表示所有 DirectXMath 功能都會使用 SSE2 指示。 不過,其他程式代碼也是如此。

DirectXMath 外部的程式代碼會使用編譯程式預設值來處理。 如果沒有此參數,產生的程式代碼通常會使用效率較低的 x87 程式代碼。

強烈建議您一律使用最新可用的編譯程式版本。

適當時使用 Est 函式

許多函式都有以 Est 結尾的對等估計函式。 這些函式會以某種精確度來提升效能。 Est 函式適用於可犧牲速度精確度的非關鍵計算。 確切的遺失精確度和速度增加量取決於平臺。

例如, XMVector3AngleBetweenNormalsEst 函式可用來取代 XMVector3AngleBetweenNormals 函 式。

使用對齊的數據類型和作業

支援 SSE2 之 Windows 版本的 SIMD 指令集,通常已對齊和未對齊的記憶體作業版本。 對齊作業的使用速度較快,而且應盡可能優先使用。

DirectXMath 連結庫可透過變異向量類型、結構和函式,提供對齊且未對齊的功能。 這些變體會以名稱結尾的 「A」 表示。

例如,XMStoreFloat4 和 XMStoreFloat4A 函式會分別使用未對齊的XMFLOAT4X4結構和對齊的XMFLOAT4X4A結構。

正確對齊配置

DirectXMath 連結庫基礎的 SSE 內建對齊版本比未對齊的要快。

基於這個理由,使用 XMVECTORXMMATRIX 物件的 DirectXMath 作業會假設這些物件會對齊 16 位元組。 如果程式代碼是使用建議的 Windows 針對 DirectXMath 連結庫進行編譯,這會針對堆棧型配置進行自動設定(請參閱 使用正確的編譯設定)編譯程式設定。 不過,請務必確保包含 XMVECTORXMMATRIX 物件的堆積配置,或轉換成這些類型,符合這些對齊需求。

雖然 64 位 Windows 記憶體配置會對齊 16 位元組,但根據預設,配置 32 位版本的 Windows 記憶體只會對齊 8 位元組。 如需控制記憶體對齊的資訊,請參閱 _aligned_malloc

使用對齊的 DirectXMath 類型與標準範本連結庫 (STL) 時,您必須提供自訂配置器,以確保 16 位元組的對齊方式。 如需撰寫自定義配置器的範例,請參閱Visual C++ Team 部落格 (而不是 malloc/free,您想要在實作中使用_aligned_malloc和_aligned_free)。

備註

某些 STL 範本會修改所提供類型的對齊方式。 例如, make_shared<> 新增一些內部追蹤資訊,這些資訊可能或可能不會遵守所提供使用者類型的對齊方式,因而產生未對齊的數據成員。 在此情況下,您必須使用未對齊的類型,而不是對齊的類型。 如果您衍生自現有的類別,包括許多 Windows 執行時間物件,您也可以修改類別或結構的對齊方式。

 

盡可能避免運算子多載

為了方便起見,許多類型,例如 XMVECTORXMMATRIX 具有常見算術運算的運算子多載。 這類運算子多載通常會建立許多暫存物件。 建議您避免在效能敏感程序代碼中使用這些運算子多載。

反正規

為了支援接近 0 的計算,IEEE 754 浮點標準包含逐步下溢的支援。 透過使用反正規化值來實作漸進式下溢,處理反正規化時,許多硬體實作速度很慢。 要考慮的優化是停用 DirectXMath 所使用向量作業的反正規性處理。

變更反正規的處理是透過在線程前階段使用 _controlfp_s 例程來完成,而且可能會導致效能改善。 使用此程式碼來變更反惡意代碼的處理:

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

備註

在 64 位版本的 Windows 上,SSE 指令會用於所有計算,而不只是向量作業。 變更反正規處理會影響程式中的所有浮點運算,而不只是 DirectXMath 所使用的向量作業。

 

利用整數浮點雙重性

DirectXMath 支援 4 個單精度浮點數或四個 32 位(帶正負號或不帶正負號)值的向量。

因為用來實作 DirectXMath 連結庫的指令集能夠將相同的數據視為多個不同類型的 ,例如,可以將相同的向量視為浮點和整數數據特定優化。 您可以使用整數向量初始化例程和位運算符來作浮點值,以取得這些優化。

DirectXMath 連結庫所使用的單精度浮點數二進位格式完全符合 IEEE 754 標準:

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

使用 IEEE 754 單精度浮點數時,請務必記住,某些表示法具有特殊意義(也就是說,它們不符合上述描述)。 範例包括:

  • 正零為 0
  • 負零為0x80000000
  • Q_NAN為 07FC0000
  • +INF 已0x7F800000
  • -INF 已0xFF800000

偏好範本表單

XMVectorSwizzleXMVectorPermuteXMVectorInsertXMVectorShiftLeft、XMVectorRotateLeftXMVectorRotateRight 的範本窗體存在。 使用這些函數形式,而不是一般函式形式,可讓編譯程式建立更有效率的實作。 針對 SSE,這通常會折疊為一或兩個_mm_shuffle_ps值。 針對 ARM-NEON,XMVectorSwizzle 範本可以利用許多特殊案例,而不是較一般的 VTBL swizzle/permute。

搭配 Direct3D 使用 DirectXMath

DirectXMath 的常見用法是執行圖形計算以搭配 Direct3D 使用。 透過 Direct3D 10.x 和 Direct3D 11.x,您可以透過下列直接方式使用 DirectXMath 連結庫:

DirectXMath 程式設計手冊