Pengoptimalan Kode dengan Pustaka DirectXMath

Topik ini menjelaskan pertimbangan dan strategi pengoptimalan dengan Pustaka DirectXMath.

Menggunakan pengaktor dengan hemat

Operasi berbasis vektor menggunakan set instruksi SIMD dan ini memanfaatkan register khusus. Mengakses komponen individual mengharuskan perpindahan dari register SIMD ke yang skalar dan kembali lagi.

Jika memungkinkan, lebih efisien untuk menginisialisasi semua komponen XMVECTOR pada satu waktu, alih-alih menggunakan serangkaian pengaktor vektor individu.

Gunakan pengaturan kompilasi yang benar

Untuk target Windows x86, aktifkan /arch:SSE2. Untuk semua target Windows, aktifkan /fp:fast.

Secara default, kompilasi terhadap target Pustaka DirectXMath untuk Jendela x86 dilakukan dengan _XM_SSE_INTRINSICS_ ditentukan. Ini berarti bahwa semua fungsiOnalitas DirectXMath akan menggunakan instruksi SSE2. Namun, hal yang sama tidak berlaku untuk kode lain.

Kode di luar DirectXMath ditangani menggunakan default pengkompilasi. Tanpa sakelar ini, kode yang dihasilkan mungkin sering menggunakan kode x87 yang kurang efisien.

Kami sangat menyarankan Agar Anda selalu menggunakan versi kompilator terbaru yang tersedia.

Gunakan fungsi Est jika sesuai

Banyak fungsi memiliki fungsi estimasi yang setara yang berakhiran Est. Fungsi-fungsi ini memperdagangkan beberapa akurasi untuk meningkatkan performa. Fungsi Est sesuai untuk perhitungan non-kritis di mana akurasi dapat dikorbankan untuk kecepatan. Jumlah akurasi yang hilang dan peningkatan kecepatan yang tepat tergantung pada platform.

Misalnya, fungsi XMVector3AngleBetweenNormalsEst dapat digunakan sebagai pengganti fungsi XMVector3AngleBetweenNormals .

Gunakan Tipe dan Operasi Data yang Diratakan

Instruksi SIMD yang ditetapkan pada versi windows yang mendukung SSE2 biasanya telah menyelaraskan dan tidak selaras dengan versi operasi memori. Penggunaan operasi yang selaras lebih cepat, dan harus lebih disukai sedapat mungkin.

Pustaka DirectXMath menyediakan fungsionalitas yang selaras dan tidak selaras dengan akses melalui jenis, struktur, dan fungsi vektor varian. Varian ini ditunjukkan oleh "A" di akhir nama.

Misalnya, ada struktur XMFLOAT4X4 yang tidak selaras dan struktur XMFLOAT4X4A yang selaras, yang masing-masing digunakan oleh fungsi XMStoreFloat4 dan XMStoreFloat4A .

Ratakan Alokasi dengan Benar

Versi intrinsik SSE yang selaras yang mendasar Pustaka DirectXMath lebih cepat daripada yang tidak diratakan.

Untuk alasan ini, operasi DirectXMath menggunakan objek XMVECTOR dan XMMATRIX mengasumsikan objek tersebut selaras dengan 16 byte. Ini otomatis untuk alokasi berbasis tumpukan, jika kode dikompilasi terhadap Pustaka DirectXMath menggunakan pengaturan pengkompilasi Windows yang direkomendasikan (lihat Menggunakan Pengaturan Kompilasi yang Benar). Namun, penting untuk memastikan bahwa alokasi tumpukan yang berisi objek XMVECTOR dan XMMATRIX , atau transmisi ke jenis ini, memenuhi persyaratan penyelarasan ini.

Sementara alokasi memori Windows 64-bit selaras dengan 16 byte, secara default pada versi 32 bit memori Windows yang dialokasikan hanya selaras 8-byte. Untuk informasi tentang mengontrol perataan memori, lihat _aligned_malloc.

Saat menggunakan jenis DirectXMath yang diratakan dengan Standard Template Library (STL), Anda harus menyediakan alokator kustom yang memastikan perataan 16 byte. Lihat blog Tim Visual C++ untuk contoh penulisan alokator kustom (alih-alih malloc/gratis, Anda mungkin ingin menggunakan _aligned_malloc dan _aligned_free dalam implementasi Anda).

Catatan

Beberapa templat STL memodifikasi perataan jenis yang disediakan. Misalnya, make_shared<> menambahkan beberapa informasi pelacakan internal yang mungkin atau mungkin tidak menghormati keselarasan jenis pengguna yang disediakan, yang mengakibatkan anggota data yang tidak selaras. Dalam hal ini, Anda perlu menggunakan jenis yang tidak selaras alih-alih jenis yang diratakan. Jika Anda berasal dari kelas yang ada, termasuk banyak objek Windows Runtime, Anda juga dapat memodifikasi perataan kelas atau struktur.

 

Hindari Kelebihan Beban Operator Jika Memungkinkan

Sebagai fitur kenyamanan, sejumlah jenis seperti XMVECTOR dan XMMATRIX memiliki kelebihan beban operator untuk operasi aritmatika umum. Kelebihan beban operator tersebut cenderung membuat banyak objek sementara. Kami menyarankan agar Anda menghindari kelebihan beban operator ini dalam kode sensitif performa.

Denormal

Untuk mendukung komputasi mendekati 0, standar float-point IEEE 754 mencakup dukungan untuk aliran bawah bertahap. Aliran bawah bertahap diimplementasikan melalui penggunaan nilai yang didenormalisasi, dan banyak implementasi perangkat keras lambat saat menangani denormal. Pengoptimalan yang perlu dipertimbangkan adalah menonaktifkan penanganan denormal untuk operasi vektor yang digunakan oleh DirectXMath.

Mengubah penanganan denormal dilakukan dengan menggunakan _controlfp_s rutin secara pra-alur, dan dapat mengakibatkan peningkatan performa. Gunakan kode ini untuk mengubah penanganan denormal:

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

Catatan

Pada Windows versi 64-bit, instruksi SSE digunakan untuk semua komputasi, bukan hanya operasi vektor. Mengubah penanganan denormal memengaruhi semua komputasi floating-point dalam program Anda, bukan hanya operasi vektor yang digunakan oleh DirectXMath.

 

Manfaatkan Integer Floating Point Duality

DirectXMath mendukung vektor 4 nilai floating-point presisi tunggal atau empat nilai 32-bit (ditandatangani atau tidak ditandatangani).

Karena set instruksi yang digunakan untuk mengimplementasikan Pustaka DirectXMath memiliki kemampuan untuk memperlakukan data yang sama dengan beberapa jenis yang berbeda-misalnya, memperlakukan vektor yang sama dengan pengoptimalan tertentu data floating-point dan bilangan bulat dapat dicapai. Anda bisa mendapatkan pengoptimalan ini dengan menggunakan rutinitas inisialisasi vektor bilangan bulat dan operator bit-wise untuk memanipulasi nilai floating-point.

Format biner dari angka floating-point presisi tunggal yang digunakan oleh Pustaka DirectXMath sepenuhnya sesuai dengan standar IEEE 754:

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

Ketika bekerja dengan angka floating-point presisi tunggal IEEE 754, penting untuk diingat, bahwa beberapa representasi memiliki arti khusus (yaitu, mereka tidak sesuai dengan deskripsi sebelumnya). Contoh meliputi:

  • Nol positif adalah 0
  • Nol negatif 0x80000000
  • Q_NAN adalah 07FC0000
  • +INF 0x7F800000
  • -INF 0xFF800000

Pilih Formulir Templat

Formulir templat ada untuk XMVectorSwizzle, XMVectorPermute, XMVectorInsert, XMVectorShiftLeft, XMVectorRotateLeft, dan XMVectorRotateRight. Menggunakan ini alih-alih bentuk fungsi umum memungkinkan pengkompilasi untuk membuat implementasi yang jauh lebih efektif. Untuk SSE, ini sering diciutkan ke satu atau dua nilai _mm_shuffle_ps. Untuk ARM-NEON, templat XMVectorSwizzle dapat menggunakan sejumlah kasus khusus daripada VTBL swizzle/permute yang lebih umum.

Menggunakan DirectXMath dengan Direct3D

Penggunaan umum untuk DirectXMath adalah melakukan komputasi grafis untuk digunakan dengan Direct3D. Dengan Direct3D 10.x dan Direct3D 11.x, Anda dapat menggunakan pustaka DirectXMath dengan cara langsung berikut:

Panduan Pemrograman DirectXMath