私は Discrete Element Method のコードを書いています。ボール(球)と壁(平面)が相互に作用しています。
これらのシミュレーションは数十億の時間ステップにわたって実行されるため、ここでのパフォーマンスは本当に重要です。現在、私はさまざまなデザインを検討しており、どちらが最適かわかりません。
私はそれらと私の疑問を説明しようとします。
ボールの1つのクラス:
class Balls:
/* contains:
geometry
forces
positions
velocities
etc.
of balls */
壁の1つのクラス:
class Walls:
/* contains:
geometry
forces
positions
velocities
etc.
of Walls */
ソルバーも含むアセンブリ:
class Assembly:
/* contains:
balls object
walls object
other parameters for the Assembly
Solver:
method to compute interactions balls-balls and walls-balls
method to advance time (time integration)
ここでの質問は、どのようにしてオーバーヘッドを少なくするかです。ソルバーは、他の2つのクラスのほとんどすべての属性にアクセスする必要があります。ゲッターを作成するか、World
クラスを他の2つのfriend
として宣言しますか?
ソルバークラス:
class Solver:
/* Contains:
some solver related parameters (e.g., step size)
Two methods:
method to compute interactions balls-balls and walls-balls
method to advance time (time integration)
壁とボールのすべての定義を含むアセンブリクラス
class Assembly:
/* contains basically all attributes of the two
classes Walls and Balls shown in the alternative 1 and
a method which calls the two methods of the class solver
by passing the balls/walls attributes by reference */
ここでも、参照によって属性を渡したり、World
クラスをfriend
クラスのSolver
として宣言したり、ゲッターを使用したりする方が良いでしょうか。
すべてを1つのクラスに結合します(実際には考慮されていません)。
最後に、オーバーヘッドを最も減らす設計は何ですか?私より良いデザインを提案できますか?
編集:注意すべきは、クラスBalls
およびWalls
では、すべてを1つのオブジェクトに格納することです。つまり、オブジェクトBalls balls
には例が含まれます(アセンブリ全体に2つのボールしか含まれていない場合):
vector<Eigen::Vector3d> ball_positions = {Eigen::Vector3d(x1,y1,z1),
Eigen::Vector3d(x2,y2,z2)}
vector<double> ball_radii = {r1,r2}
パフォーマンスが危機に瀕している場合、確実に知る唯一の方法はベンチマークです。
代替1には、ポリモーフィズムを使用する場合、簡単に拡張できるという利点があります。
class SimulationObject {
// common properties
// virtual functions for anything that changes according to real objects
};
class Sphere: public SimulationObject {
...
};
class Wall: public SimulationObject {
...
};
仮想関数 は、余分な間接参照があるため、わずかなオーバーヘッドがあります(最近のCPUでは大した問題ではありません)。ただし、タイプによって動作を変えるために必要な追加の条件付きステートメントと比較すると、これは無視できます。
double dispatch を使用して、さまざまな種類のオブジェクト間の可能な相互作用の組み合わせの爆発に非常に効果的に対処できます。今日は球と球だけです。しかし、球、立方体、壁がある場合はどうでしょうか。壁にぶつかる前に、球が他の球または立方体で跳ねる可能性がある場所
他の選択肢は本当に私には持続可能ではないようです。また、条件付きの長いチェーンを通過して、特定の相互作用/組み合わせの特定のケースを把握する必要がある場合、パフォーマンスが向上するかどうかはわかりません。