問題タブ [data-oriented-design]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
rust - Rust でデータ指向設計を実装するにはどうすればよいですか?
バックグラウンド
ゲーム エンジンの開発では、メモリと計算のパフォーマンスを最適化するために、通常はデータ指向の設計を使用します。
パーティクルシステムを例に取りましょう。
粒子システムには多数の粒子があり、各粒子は位置、速度などのいくつかの属性を持つ場合があります。
C++ での典型的な実装は次のようになります。
この実装の問題の 1 つは、パーティクルの属性が相互にインターリーブされることです。このメモリ レイアウトはキャッシュに適していないため、SIMD 計算には適していない可能性があります。
データ指向の設計ではなく、次のコードを記述します。
これで、割り当ては 1 つだけになり、各属性はメモリ内に継続的に存在します。粒子をシミュレートするには、次のコードを記述します。
このgetAttribute
関数は、特定の属性の開始アドレスを取得します。
質問
これをRustに実装する方法を知りたいです。
私の考えは、最初に というクラスを作成することです。これは、合計バッファーサイズを計算するのにParticleSystem
数秒かかり、次にバッファーにメモリを割り当てます。ParticleAttribute
これはRustセーフなコードでできると思います。
次のステップはgetAttribute
、特定の属性の開始アドレスへの参照を返す関数を実装することです。ここであなたの助けが必要です。オフセットを使用して生のアドレスを取得し、それを目的の型 (float* など) にキャストし、その生のポインターを Rust の可変参照にラップするにはどうすればよいですか?
さらに、SIMD ライブラリを使用してその参照を介して 4 つの要素をロードする必要があるため、配列への変更可能な参照への生のポインターをラップする必要があると思います。Rustを使用してこれを達成するにはどうすればよいですか?
更新: 属性に関する詳細情報を提供します。属性の数と詳細情報は実行時に決定されます。属性のタイプはさまざまですが、プリミティブなもの (f32、f64、ints など) のみをサポートする必要があると思います。
c++ - なぜこのコードは非常に遅いのですか?キャッシュの動作に関連するものはありますか?
データ指向の設計実験を始めました。私は最初にいくつかの oop コードを実行し始めましたが、一部のコードが非常に遅いことがわかりました。理由はわかりません。ここに一例があります: 私はゲームオブジェクトを持っています
次に、new を使用して 1,000,000 個のオブジェクトを作成し、UpdateFoo() の呼び出しをループします。
ループを終了するには約 20ms かかります。そして、float m_Pos[2] をコメントアウトすると奇妙なことが起こったので、オブジェクトは次のようになります
そして突然、ループが完了するまでに約150msかかります。そして、m_Vel の前に何かを置くと、はるかに速くなります。m_Vel と m_Foo の間、または m_Vel....slow の前の場所を除く他の場所にパディングを入れようとします。
リリース ビルド i7-4790 で vs2008 と vs2010 をテストしました。キャッシュの一貫した動作に関連していますか。
ここにサンプル全体があります: