2D Vector sınıfı için float, double veya her ikisi mi?


11

Şu anda stüdyomuz için küçük bir platformlar arası OpenGL tabanlı 2D oyun motoru yazıyorum. Hangi 2D Vector sınıfını kullanacağımı araştırdığımda, üç farklı tasarım paradigmasına rastladım:

  • Bu Gamasutra makalesinde olduğu gibi kayan ve değere göre çağrı . Hızlı görünüyor, ancak çok az hassasiyet sunuyor (ayrıca bu Konuya bakın ). Pro: Hızlı, taşınabilir ve çoğu kütüphane ile uyumludur.

  • Çift ve referans çağrı. Yukarıdaki makaleyi doğru anlarsam, 4 kayan sayı yerine 2 çift kesinlikli değişken de kullanabilirim. Yukarıdaki ipliğe göre çift şamandıradan hala daha yavaştır.

  • Double ve float için şablon: Yaygın olarak popüler olan " Game Engine Architecture " kitabı, float ve double'ı gerektiği gibi kullanmayı mümkün kılmak için şablonlar kullanır. Açık olan dezavantajı kod şişmesidir. Ayrıca, kod temelde zaten iki sınıf yazmadan optimize edilebilir şüpheliyim.

Şirket içi motorlarınızda hangi çözümleri kullandığınızı ve örneğin popüler oyun motorlarının ne kadar hassas olduğunu öğrenmek için minnettar olurum, böylece motorumuzda hangi çözümü uygulayacağım konusunda karar verebilirim. Şu anda şamandıra hassasiyetini kullanmayı ve onunla yaşamayı düşünüyorum.


Daha yavaş nerede ? Belirli bir mimariye bağlı değilse hız hakkında konuşamazsınız.
o0 '.

2
@ Lo'oris: Çiftin şamandıradan daha hızlı olduğu hiçbir mimari bilmiyorum.

Kendi vektör sınıfınızı yazmak yerine, Sony'nin ( bulletphysics.org/Bullet/phpBB3/… ) kullanmayı düşünün . Zaten mikro optimize edilmiş, kolay açılan sadece başlık "kütüphanesi" dir ve tüm vektör kütüphaneleri temelde aynı harici arayüzdür.

@Joe: 4 şamandıra yerine 2 çift mi?
o0 '.

@ Lo'oris: Soru biraz garip, soru soran kişinin kafasını karıştırıyor mu yoksa sadece sen - bilmiyorum "SIMD ile uğraşırken dört şamandıra yerine" iki kat kullanıyorsunuz, çünkü kayıt 128 bit genişliğindedir. Yine de eşit sayıda sayıyı işlemeniz gerekiyor ve bunu yarı hızda yapıyorsunuz.

Yanıtlar:


9

Ben int64_t kullanmak için bir neden olmadığı sürece int kullanmak gibi, ben çift kullanmak için bir neden olmadığı sürece her zaman float kullanın.

Şamandıralar çoğu insanın (çoğunlukla irrasyonel olarak) korktuğu 2 24'e kadar tamsayı aritmetiği yapmakta sorun yaşamaz. Çiftler, ortak değerler sorununu tam olarak temsil edilemez olarak çözmez - 0.10000001 veya 0.10000000000000001 olsun, kodunuzun 0.09999999'a "eşit" olduğunu düşündüğünüzden emin olmalısınız.

Oyun yazmayı önemsediğiniz her platformda iki kat daha yavaştır, bellek bant genişliğinin iki katını alır ve daha az özelleştirilmiş CPU talimatına sahiptir.

Tek duyarlıklı şamandıralar, hem C / C ++ tarafında hem de iç gölgelendiricilerde donanım grafik arabirimleri için standart olarak kalır.

Muhtemelen bir noktada çift vektöre ihtiyacınız olacaktır, ancak varsayılan olarak değil, gerektiğinde kullanılmalıdır.

Ayarlamaya gelince - haklısınız, maksimum performans için şablonları yine de manuel olarak uzmanlaşmak isteyeceksiniz. Bunun yanı sıra, hafta sonu boyunca bazı templated kodlar için bazı testler yaptım (4 ple IntRect ve FloatRect yapma) ve templated versiyonun derlemek için kodun tekrarlanmasından yaklaşık 20 kat daha uzun sürdüğünü gördüm, bu da yaklaşık 15 satırdı . Tekrarlama berbat, ancak derlemeleri beklemek daha fazla berbat - ve bir StringRect veya FooRect'e ihtiyacım olacak gibi değil.


" Çiftler her platformda daha yavaş […] " - Atıf gerekli.
zenith

3

Microsoft XNA oyun çerçevesi, float kullanan bir Vector2 sınıfına sahiptir. XNA ekibinin bilgeliğinin ve deneyiminin kendiminkinden çok daha büyük olduğuna inandığım için, bu, yüzerek gitmek için en büyük kişisel nedenim olacak.

Bu Stack Overflow sorusunun cevabını okumak oldukça ilginç buldum: "Float vs Double Performance" . GPU'larda çifte performans tartışması yapan bir gamedev.net iş parçacığı da var . En azından birçok GPU'da çiftlerin yüzenlerden daha yavaş olduğunu varsaymanın güvenli olduğunu düşünüyorum ve şahsen her zaman çift meslektaşları üzerinde şamandıra OpenGL işlevlerini kullandım. Bu, bugünlerde geçerli olmayabilir, ancak oyununuzu çalıştıran herkesin yerel çift desteğe sahip en son GPU'ya sahip olmadığını düşünüyorsanız, bunun şamandıraları kullanmak ve ekstra performans elde etmek için yeterli bir neden olduğunu düşünüyorum.


1
SO sorusundan: "En azından x86 işlemcilerde, float ve double her biri FPU tarafından işlenmek üzere 10 baytlık bir gerçek değere dönüştürülecek." Bu doğru olsa da, hem SIMD talimatlarını hem de ek bellek (= daha kötü önbellek tutarlılığı, daha fazla bellek bant genişliği) ikiye katlama gereksinimlerini ihmal eder, her ikisi de gerçek dünya testlerinde yüzmekten daha yavaş olmaya devam eder.

Bir yakalama olduğunu düşündüm. SO cevabı üzerine yorum yapmalısın.
Ricket

Zaten bir yorum olarak var.

1
XNA'yı getirdiğinden beri Direct2D'nin tek duyarlıklı şamandıralar kullandığını da belirtebilirim.
Mike Strobel

Ve tamlık için, OpenGL'nin float ve yöntemlerinin çift versiyonları vardır, bu nedenle bu anlamda tarafsızdır.
Ricket
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.