私の質問は基本的にタイトルに完全に記載されていますが、詳しく説明させてください。
質問:virtual
メカニズムをかなりのオーバーヘッドにするために、メソッドが
どれほど複雑/単純でなければならないか、言い換える価値があるでしょうか?これには経験則がありますか?たとえば、10 分かかる場合、I/O、複雑なif
ステートメント、メモリ操作などを使用しても問題ありません。または、virtual get_r() { return sqrt( x*x + y*y); };
ループで記述して呼び出すと、問題が発生します。
一般的ではあるが具体的な技術的な回答を求めているので、質問が一般的すぎないことを願っています。伝えるのが難しい/不可能であるか、仮想呼び出しには非常に多くの時間/サイクルリソースが必要であり、数学はこれを、I/O はこれを必要とします。
おそらく、一部の技術者は、比較する一般的な数値を知っているか、何らかの分析を行い、一般的な結論を共有できます。恥ずかしいことに、私はそれらの凝ったasm
分析を行う方法を知りません =/.
また、その背後にある理論的根拠と、私の使用例も示したいと思います。
パフォーマンスのために、干ばつ時に森林でのたき火のような仮想の使用を控えている人々や、「あなたの場合、仮想オーバーヘッドが本当に問題であると確信していますか? ?」。
最近の仕事で、川の両側に配置できる問題に遭遇したと思います。
また、インターフェイスの実装を改善する方法を尋ねていないことも覚えておいてください。私はそれを行う方法を知っていると信じています。いつそれを行うか、またはどちらを選択するかを判断できるかどうかを尋ねています。
使用事例:
いくつかのシミュレーションを実行します。基本的に実行環境を提供するクラスがあります。基本クラスと、いくつかの異なるワークフローを定義する複数の派生クラスがあります。Base は共通ロジックとしてものを収集し、I/O ソースとシンクを割り当てます。派生物は、多かれ少なかれ実装することによって、特定のワークフローを定義しますRunEnv::run()
。これは有効な設計だと思います。ここで、ワークフローの対象であるオブジェクトを 2D または 3D 平面に配置できると想像してみましょう。ワークフローはどちらの場合も共通/交換可能であるため、作業中のオブジェクトは共通のインターフェースを持つことができますが、Object::get_r()
. その上で、環境用にいくつかの統計ロガーを定義できます。
もともと私はいくつかのコード スニペットを提供したかったのですが、最終的には 5 つのクラスとそれぞれ 2 ~ 4 つのメソッド (つまり、壁) になりcode
ました。リクエストに応じて投稿できますが、質問が現在のサイズの 2 倍に長くなります。
キー ポイントは次RunEnv::run()
のとおりです。 メイン ループです。通常、非常に長い (5 分~5 時間)。基本的な時間計装、呼び出しRunEnv::process_iteration()
、およびRunEnv::log_stats()
. すべて仮想です。根拠は。を導出し、たとえばさまざまな停止条件に合わせて をRunEnv
再設計できます。たとえば、オブジェクトのプールを処理する必要がある場合にマルチスレッドを使用して、さまざまな方法で処理するようにrun()
再設計できます。process_iteration()
また、異なるワークフローでは、異なる統計をログに記録する必要があります。RunEnv::log_stats()
すでに計算された興味深い統計を に出力する単なる呼び出しですstd::ostream
。仮想を使用していると思いますが、実際の影響はありません。
ここで、原点までのオブジェクトの距離を計算することによって反復が機能するとしましょう。したがって、インターフェイスとして持っていますdouble Obj::get_r();
。Obj
2D および 3D ケースの実装です。どちらの場合も、ゲッターは 2 ~ 3 回の乗算と加算による単純な計算です。
また、さまざまなメモリ処理を試しました。たとえば、座標データはプライベート変数に保存されることもあれget_x()
ば、共有プールに保存されることget_x(){return x;};
もありましたget_x(){ return pool[my_num*dim+x_offset]; };
。で何かを計算することを想像してみてくださいget_r(){ sqrt(get_x()*get_x() + get_y()*get_y()) ;};
。ここでの仮想化がパフォーマンスを低下させるのではないかと思います。