0

各ステップで dy/dx を評価し、その後は必要ない ODE インテグレーターを作成しています。新しいdydxベクトルの割り当てに時間を費やさないように、スペースのみを割り当ててそのスペースを使用する方が速いようです。コンパイラはこれを最適化しますか? 言い換えれば、どちらが優れていますか?

1)

vector<double> dydx(const vector<double>&x) {
  vector<double> dydx_tmp(x.size());
  for(size_t i = 0; i < x.size()/2; ++i) {
    dydx_tmp[2*i] = -x[2*i+1]; 
    dydx_tmp[2*i+1] = x[2*i];
  } 
  return dydx_tmp;
}

または 2)、dydx が既に割り当てられており、更新が必要な場合

void update_dydx(vector<double> & dydx, const vector<double> &x) {
  for(size_t i = 0; i < x.size()/2; ++i) {
    dydx[2*i] = -x[2*i+1]; 
    dydx[2*i+1] = x[2*i];
  } 
}

3)の場合もある

vector<double> dydx_by_v(vector<double> x) {
  vector<double> dydx_tmp(x.size());
  for(size_t i = 0; i < x.size()/2; ++i) {
    dydx_tmp[2*i] = -x[2*i+1]; 
    dydx_tmp[2*i+1] = x[2*i];
  } 
  return dydx_tmp;
}

これはhttp://cpp-next.com/archive/2009/08/want-speed-pass-by-value/に従いますが、この場合、xのメモリは後で出力に使用されるため問題ありません。コンパイラの RVO では使用できません。

4

1 に答える 1

0

パフォーマンスに関連するすべての質問に対する究極の答えは、実稼働環境で実行されるものと同じ (または少なくとも同様の) ハードウェアでアプリ全体をプロファイリングすることですが、ここに私の理論作成の 3 セントを示します。

  • オプション 3) の値渡しは意味がありません

  • ベクトル dydx_tmp(x.size()); <-これにより、デフォルトでベクトルが構築されます(別名ゼロ化)。ベクトル dydx を使用します。dydx.reserve(x.size()); そして、ループ内で emplace_back() (名前に _temp を追加しても意味がありません - 誰もがそれがローカルであることを確認できます)

  • オプション2)には、スタイルが悪いと見なされる入力パラメーターが含まれており、オプション1)にはコピーがありません(リンクした記事で説明されているように)とにかく(リンクした記事で説明されているように)、1)が最適なオプションです

于 2013-07-09T15:17:06.427 に答える