Vector3 vs. Vector2 - kinerja, penggunaan?

8

Saat ini saya bermain-main dengan XNA, dan membuat platformer 2D sederhana. Saya sedang berpikir untuk menambahkan beberapa layer untuk membuatnya sedikit tantangan.

Sebagai ganti memiliki Vector2untuk posisi saya, saya sekarang menggunakan Vector3, hanya untuk menggunakannya Zsebagai kedalaman lapisan. Namun, karena Anda tidak dapat menggunakan operator antara Vector2dan Vector3karena alasan yang tidak diketahui [1] , saya akhirnya mengubah semua yang lain Vector2dalam permainan saya, seperti akselerasi , kecepatan , dan offset , sehingga saya dapat melakukan hal-hal seperti position += offsettanpa kesalahan.

Saya juga mengubah variabel rotasi saya dari floatmenjadi Vector3, dan saya menggunakan Znilai untuk memutar tekstur saya. Saya berencana untuk menggunakan Xdan Yuntuk skala-balik tekstur saya, sehingga Anda mendapatkan efek Super Paper Mario.

Namun, setelah mengubah semua ini Vector2di Vector3s, saya merasa agak buruk tentang hal itu. Bagaimana ini mempengaruhi kinerja game? Saya tahu saya tidak perlu khawatir tentang kinerja dalam permainan platformer kecil saya, tapi saya hanya ingin tahu tentang hal itu.

Apakah ada kinerja mencolok antara Vector2s dan Vector3s, misalnya saat menambahkan atau mengalikan mereka, atau saat memanggil Normalize, Transformatau Distance?


[1] Hanya pertanyaan sampingan, mengapa tidak ada operator untuk penghitungan antara Vector3 dan Vector2?

Rudey
sumber

Jawaban:

13

Apakah ada kinerja mencolok antara Vector2s dan Vector3s, misalnya saat menambahkan atau mengalikan mereka, atau saat memanggil Normalize, Transformatau Distance?

Ya, Anda memiliki satu lagi koordinat sehingga Anda akan menggunakan lebih banyak siklus CPU.

Tetapi sangat tidak mungkin hal itu akan memberi Anda masalah. XNA 4 menggunakan ekstensi SIMD untuk matematika vektor (EDIT: hanya pada Windows Phone ), sehingga implementasinya sangat optimal (pada platform itu). Kecuali jika Anda melakukan komputasi yang sangat berat, sangat kecil kemungkinannya akan menyebabkan masalah bagi Anda. Anda memang perlu Vector3untuk posisi Anda karena Anda sekarang sedang melakukan 3D (atau 2.5D ...), jadi tolong jangan lakukan optimasi prematur. Ini adalah 97% jahat 1 .

Hanya pertanyaan sampingan, mengapa tidak ada operator untuk perhitungan antara Vector3 dan Vector2?

Karena tidak masuk akal, secara matematis. Apa yang Anda harapkan dari perhitungan seperti itu? Misalnya apa yang harus terjadi jika Anda mencoba menambahkan Vector3dan Vector2:

[ x1, y1, z1 ] + [ x2, y2 ] = [ x1 + x2, y1 + y2, z1 ] atau [ x1, y1 + x2, z1 + y2 ]?

Dalam hal ini, Anda biasanya perlu menentukan sendiri apa yang Anda inginkan sebagai koordinat ketiga untuk Vector2, dan di mana Anda ingin menambahkannya. Misalnya ini memecahkan ambiguitas:

[ x1, y1, z1 ] + [ x2, y2, 0 ] = [ x1 + x2, y1 + y2, z1 ]


Sekarang mungkin beberapa bagian gameplay Anda hanya berfungsi dalam 2D. Jika ada kasus di mana Anda hanya perlu koordinat 2D, dan jika komputasi tidak mendapatkan benar-benar berat (misalnya 2D fisika), Anda dapat menempel Vector2dalam yang spesifik bagian dari kode untuk menghemat siklus berharga. Anda kemudian dapat dengan mudah beralih di antara koordinat 2D dan 3D ketika Anda perlu (mis. Mendapatkan posisi adegan dari posisi fisika 2D, atau sebaliknya):

Misalnya dari Vector2ke Vector3menggunakan konstruktor ini :

Vector2 v2;
Vector3 v3(v2, someDepthValue);

Atau dari Vector3ke Vector2menggunakan konstruktor yang ;

Vector3 v3;
Vector2 v2(v3.X, v3.Y);

1 Dalam kata-kata Donald Knuth :

Programmer menghabiskan banyak waktu untuk memikirkan, atau mengkhawatirkan, kecepatan bagian nonkritis dari program mereka, dan upaya efisiensi ini sebenarnya memiliki dampak negatif yang kuat ketika debugging dan pemeliharaan dipertimbangkan. Kita harus melupakan efisiensi kecil, katakanlah sekitar 97% dari waktu: optimasi prematur adalah akar dari semua kejahatan . Namun kita tidak boleh melewatkan peluang kita dalam 3% kritis itu.

Laurent Couvidou
sumber
Seperti yang saya katakan, saya tahu saya tidak perlu khawatir tentang kinerja begitu cepat, tetapi hanya rasa ingin tahu saya yang membuat saya memposting pertanyaan ini. Saya kira Anda benar tentang ambiguitas . Terima kasih atas jawaban yang jelas :)
Rudey
@RuudLenders Saya telah menambahkan detail tentang bagaimana Anda dapat melanjutkan jika Anda pernah menghadapi masalah kinerja.
Laurent Couvidou
Saya telah mengedit jawaban Anda untuk memasukkan poin yang sangat penting: SIMD hanya digunakan oleh XNA di Windows Phone! .NET runtime di PC - dan karenanya XNA itu sendiri - tidak mendukung SIMD. Setara juga tidak didukung di Xbox 360.
Andrew Russell
(Pada PC dan Xbox 360, Memahami Kinerja Kerangka XNA masih merupakan panduan yang berlaku untuk mengoptimalkan operasi vektor Anda.)
Andrew Russell
Optimalisasi prematur bukanlah kejahatan. Hanya optimasi prematur yang tidak berguna. Anda perlu mengesampingkannya dengan alasan tidak berguna , bukan dengan alasan terlalu dini.
sam hocevar
3

Anda mencoba mengoptimalkan secara prematur. Sebagian besar operasi yang Anda sebutkan (menormalkan, mengubah, jarak) cukup banyak identik dengan apa yang dilakukan vector2D, jika Anda dapat melihat kode mereka, Anda akan melihat bahwa mereka praktis sama. Satu-satunya perbedaan adalah vector3D memiliki sumbu ketiga. Kinerja bijaksana itu harus sepele dibandingkan dengan Vector2D.

Adapun pertanyaan sampingan Anda:
Karena Anda tidak dapat melipatgandakan matriks / baris-vektor / kolom-vektor yang keduanya memiliki ukuran yang berbeda.

Sidar
sumber
1

Salah satu efek kinerja terbesar dari menggunakan yang Vector3tidak perlu, alih-alih Vector2, adalah peningkatan ukuran 50% dan efek yang ada pada cache .

Bahwa data tambahan yang tidak perlu perlu dimuat ke dalam cache CPU dari memori utama. Ini sloooow .

Selain itu, dengan memuat data yang tidak perlu ini, Anda meningkatkan kemungkinan mendorong data berguna yang kemudian harus segera dimuat kembali ke cache.

Dalam loop ketat sederhana, efek cache akan membanjiri setiap efek CPU melakukan operasi tambahan.

Juga, lebih cepat untuk menambahkan elemen secara langsung (karena berbagai kebiasaan. NET). Jadi, jika Anda mengoptimalkan mikro, Anda tidak akan menggunakan operasi vektor. Jadi jika Anda hanya perlu menambahkan dua elemen pertama vektor, Anda bisa melakukan ini:

v1.X += v2.X; v1.Y += v2.Y;

Tetapi pertimbangan kinerja semacam ini hanya benar-benar berlaku untuk hal-hal seperti mesin partikel, mesin fisika, dan sebagainya. Jadi jangan terlalu khawatir!

Andrew Russell
sumber
Jadi, apakah inlining manual masih merupakan cara tercepat untuk pergi bahkan dengan dukungan tambahan SIMD?
Mikael Högström
1
@ MikaelHögström SIMD adalah hampir pasti akan menjadi lebih cepat - tetapi hanya tersedia pada platform Windows Phone (lihat edit dan komentar saya membuat jawaban Laurent Couvidou ini).
Andrew Russell