Pengoptimalan Kode dengan Pustaka DirectXMath
Topik ini menjelaskan pertimbangan dan strategi pengoptimalan dengan Pustaka DirectXMath.
- Menggunakan pengaktor dengan hemat
- Gunakan pengaturan kompilasi yang benar
- Gunakan fungsi Est jika sesuai
- Gunakan Tipe dan Operasi Data yang Diratakan
- Ratakan Alokasi dengan Benar
- Hindari Kelebihan Beban Operator Jika Memungkinkan
- Denormal
- Manfaatkan Integer Floating Point Duality
- Pilih Formulir Templat
- Menggunakan DirectXMath dengan Direct3D
- Topik terkait
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:
Gunakan konstanta namespace warna langsung di parameter ColorRGBA dalam panggilan ke metode ID3D11DeviceContext::ClearRenderTargetView atau ID3D10Device::ClearRenderTargetView . Untuk Direct3D 9, Anda harus mengonversi ke jenis XMCOLOR untuk menggunakannya sebagai parameter Warna dalam panggilan ke metode IDirect3DDevice9::Clear .
Gunakan jenis XMFLOAT4/XMVECTOR dan XMFLOAT4X4/XMMATRIX untuk mengatur struktur buffer konstan untuk referensi berdasarkan jenis HLSL float4 atau matrix/float4x4.
Catatan
XMFLOAT4X4/Jenis XMMATRIX dalam format utama baris. Oleh karena itu, jika Anda menggunakan sakelar kompilator /Zpr (bendera kompilasi D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR ) atau menghilangkan kata kunci row_major saat Anda mendeklarasikan jenis matriks di HLSL, Anda harus mengubah urutan matriks saat Anda mengaturnya ke dalam buffer konstanta.
Dengan Direct3D 10.x dan Direct3D 11.x, Anda dapat mengasumsikan bahwa penunjuk yang dikembalikan oleh metode Peta (misalnya, ID3D11DeviceContext::Map) di anggota pData (D3D10_MAPPED_TEXTURE2D.pData, D3D10_MAPPED_TEXTURE3D. pData, atau D3D11_MAPPED_SUBRESOURCE. pData) diratakan 16-byte jika Anda menggunakan tingkat fitur 10_0 atau lebih tinggi atau setiap kali Anda menggunakan sumber daya D3D11_USAGE_STAGING .