2D Vectorクラスのフロート、ダブル、または両方?


11

私は現在、スタジオ用の小さなクロスプラットフォームのOpenGLベースの2Dゲームエンジンを書いています。使用する2D Vectorクラスを調査したとき、3つの異なる設計パラダイムに出くわしました。

  • このガマスートラの記事のように、フロート&値渡し。高速に見えますが、精度はほとんどありません(このThreadも参照してください)。プロ:高速でポータブルで、ほとんどのライブラリと互換性があります。

  • 参照による二重呼び出し。上記の記事を正しく理解していれば、4つの浮動小数点数の代わりに2つの倍精度変数を使用することもできます。上記のスレッドによると、ダブルはフロートよりも遅いです。

  • doubleとfloatのテンプレート:広く普及している本「Game Engine Architecture」では、テンプレートを使用して、必要に応じてfloatとdoubleを使用できるようにしています。明らかな欠点は、コードの膨張です。また、基本的に2つのクラスを記述せずにコードを最適化できるかどうかは疑問です。

社内エンジンで使用しているソリューションや、人気のあるゲームエンジンなどの精度を確認していただければ、エンジンに実装するソリューションを決定できます。現時点では、単純に浮動小数点精度を使用してそれと共存することを考えています。


どこが遅い?速度が特定のアーキテクチャに関連付けられていない場合、速度について話すことはできません。
o0 '。

2
@ Lo'oris:doubleがfloatより速いアーキテクチャは知りません。

独自のベクタークラスを作成するのではなく、Sonyの使用を検討してください(bulletphysics.org/Bullet/phpBB3/…)。これは、すでにマイクロ最適化された、簡単なドロップインヘッダーのみの「ライブラリ」であり、すべてのベクトルライブラリは基本的に同じ外部インターフェイスです。

@ジョー:4つの浮動小数点数ではなく2つの倍精度浮動小数点数?
o0 '。

@ Lo'oris:質問は少し奇妙な言葉で書かれています。質問者が混乱しているのか、それともあなただけなのかはわかりません。SIMDを処理するとき、レジスタが128ビット幅であるため、4つの浮動小数点数の代わりに2つの倍精度浮動小数点数を使用します。同じ数の数値を処理する必要があり、半分の速度で処理しています。

回答:


9

doubleを使用する理由がない限り、常にfloatを使用します。int64_tを使用する理由がない限り、intを使用するのと同じです。

フロートは、2 24までの正確な整数演算を問題なく実行できます。これは、ほとんどの人が(ほとんどの場合、不合理に)恐れていることです。doubleは、一般的な値が正確に表現できないという問題を解決しません。0.10000001と0.10000000000000001のどちらを取得しても、コードがそれを0.09999999と「等しい」と見なしていることを確認する必要があります。

ダブルスは、ゲームを作成するすべてのプラットフォームで遅くなり、メモリ帯域幅が2倍になり、利用できる特殊なCPU命令が少なくなります。

単精度浮動小数点数は、C / C ++側と内部シェーダーの両方で、ハードウェアグラフィックスインターフェイスの標準のままです。

おそらく、ある時点でdoubleベクトルが必要になりますが、デフォルトではなく、必要なときに使用する必要があります。

テンプレートについては-そうです、最大のパフォーマンスを得るには、とにかく手動でテンプレートを特化する必要があります。それとは別に、私は週末にいくつかのテンプレートコードに対していくつかのテストを実行し(4倍のIntRectとFloatRectを作成)、テンプレートバージョンは、コードを繰り返すだけの場合よりもコンパイルに約20倍長い時間がかかることを発見しました。 。繰り返しはひどいですが、コンパイルを待つのはもっとひどいです-そして、私がStringRectやFooRectを必要とするようなことは決してありません。


ダブルスはすべてのプラットフォームで遅い[…]」–引用が必要です。
ゼニス

3

Microsoft XNAゲームフレームワークには、フロートを使用するVector2クラスがあります。XNAチームの知恵と経験は自分のものよりもはるかに優れていると信じているため、これがフロートを使用する個人的な最大の理由になります。

このスタックオーバーフローの質問「フロート対ダブルパフォーマンス」の回答を読むのは興味深いと思いました。GPUの2倍のパフォーマンスについての議論があるgamedev.netスレッドもあります。少なくとも多くのGPUでは、doubleの方がfloatよりも遅いと考えるのが安全だと思います。個人的には、float型のOpenGL関数をdouble型よりも常に使用しました。これは最近は当てはまらないかもしれませんが、ゲームを実行するすべての人がネイティブのダブルサポートを備えた最新のGPUを使用しているわけではないと考えるなら、これがフロートを使用してパフォーマンスをさらに向上させる十分な理由だと思います。


1
SOの質問から:「x86プロセッサでは、少なくとも、floatとdoubleはそれぞれ、処理のためにFPUによって10バイトの実数に変換されます。」これは事実ですが、SIMD命令と追加メモリ(=キャッシュコヒーレンシの悪化、メモリ帯域幅の増加)の両方の要件であるdoubleを無視しているため、どちらも実際のテストではフロートよりも低速になっています。

私は問題があったと思った。あなたはそれをSOの回答にコメントすべきです、私はそれを賛成します。
リケット

コメントとしてすでにそこにあります。

1
XNAを取り上げたので、Direct2Dも単精度浮動小数点を使用していることも指摘しておきます。
Mike Strobel、

そして完全を期すために、OpenGLはメソッドの浮動バージョンと二重バージョンを持っているので、この意味で中立です。
リケット
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.