7

私の質問は基本的にタイトルに完全に記載されていますが、詳しく説明させてください。

質問: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();Obj2D および 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()) ;};。ここでの仮想化がパフォーマンスを低下させるのではないかと思います。

4

4 に答える 4

8

これには経験則がありますか?

このような質問に対する最良の、最も一般的な経験則は次のとおりです。

最適化する前にコードを測定する

測定せずにコードのパフォーマンスを向上させようとすると、コードが必要以上に複雑になり、間違った場所で最適化されてしまう可能性があります。

したがって、仮想関数が問題であるという確固たる証拠が得られるまでは、仮想関数のオーバーヘッドについて心配する必要はありませんvirtual。そのような証拠がある場合はvirtual、その場合の削除に取り組むことができます。ただし、計算を高速化する方法や、必要のない場所での計算を回避する方法を見つけることで、パフォーマンスが大幅に向上する可能性が高くなります。もう一度言いますが、ただ推測するのではなく、まず測定してください。

于 2013-07-08T17:16:19.750 に答える