9

通常、標準テンプレート ライブラリが数値計算/科学計算のコードでパフォーマンス/速度のオーバーヘッドを招くかどうかを知りたいと思っています。

たとえば。配列を次のように宣言しています

double 2dmatrix [10][10]

よりも多くのパフォーマンスを提供します

std::vector<std::vector<double> > 2dmatrix(10,std::vector<double>(10,0.0))

?

また、科学計算において C が C++ よりも優れたパフォーマンスを発揮するかどうかについて、いくつかの一般的なアイデアをいただければ幸いです。私は STL を使用し、C++11 を多用して、非常にオブジェクト指向のスタイルでコードを作成しました。より高速に実行される場合は、純粋な C を検討する必要があるかどうかを検討し始めています。

これについての考えは大歓迎です。

4

7 に答える 7

9

std::vector のオーバーヘッドは次のとおりです。

  • スタック上の 3 つのポインター
  • 動的割り当て (遅延、つまり、必要になるまで何も割り当てません)

場合によっては (少量のデータの場合)、スタック割り当て配列の方が高速になることがあります。これには、 を使用できますstd::array<T, Length>

2 次元グリッドが必要な場合は、データを 1 つのベクトルに割り当てますstd::vector<T>(width * height);。次に、x 座標と y 座標で要素を取得するヘルパー関数をいくつか記述できます。(または、ラッパー クラスを作成することもできます。)

于 2013-08-20T18:37:12.760 に答える
3

人々は「あなたが何をしているかによる」と言うでしょう。

そして、彼らは正しいです。

ここは、一連の 6 つのステージを使用して従来の方法で設計されたプログラムのstd::vectorパフォーマンスが調整され、その実行時間が作業単位あたり 2700 マイクロ秒から 3.7 マイクロ秒に短縮され、730 倍のスピードアップ係数が得られた例があります。

最初に行ったことは、配列の拡張と配列からの要素の削除に多くの時間が費やされていることに気付きました。そのため、別の配列クラスが使用され、時間が大幅に短縮されました。

2 番目に行われたことは、大部分の時間がまだアレイ関連のアクティビティに費やされていることに気付きました。したがって、配列は完全に削除され、代わりにリンクされたリストが使用され、別の大幅な高速化が実現しました。

new次に、 ing やdeleteing オブジェクトなど、残りの時間の大部分を使用していました。次に、これらのオブジェクトがフリー リストで再利用され、さらに大幅な高速化が実現しました。さらに数段階後、改善点を見つけるのが難しくなり、スピードアップが十分であると判断されたため、試行を中止するという決定が下されました。

要点は、強く推奨されるものを選択してから、最善を期待するだけではいけないということです。むしろ、何らかの方法で構築してから、このようにパフォーマンス チューニングを行い、多くの時間が費やされていることに基づいて、データ構造の設計に大幅な変更を加えることをいといません。そしてそれを繰り返します。ストレージ スキームを A から B に変更し、後で B から C に変更することもできます。それはまったく問題ありません。

于 2013-08-20T19:17:57.217 に答える
3

配列のサイズを変更する理由がなく、(最初の例のように) コンパイル中にそのサイズがわかっている場合、STL テンプレートのより良い選択はstd::arrayテンプレートです。これは、C スタイルの配列と同じ利点をすべて提供します。

double 2dmatrix[10][10];

// would become

std::array<std::array<double, 10>, 10> 2dmatrix;
于 2013-08-20T18:39:03.907 に答える
1

科学計算では、大量のデータが正しく処理されず、貴重な時間が浪費されるため、バグや最適化されていないコードは特にイライラさせられます。

std::vector内部の仕組みに関する知識に応じて、ボトルネックまたは最高のパフォーマーになる可能性があります。reserve()insert()、 に特に注意してくださいerase()。プログラムがスレッド化されている場合は、アラインメントとプロセッサ キャッシングについて学習することを検討してください。

すべてのメモリ管理を自分で行おうとする場合、特にソフトウェアに機能を徐々に追加している場合は、一貫性を確保し、後でバグを探すために費やさなければならない時間を考えてみてください。結局のところ、 std::vector のオーバーヘッドは問題の中で最も少なくなります。

于 2013-08-21T03:17:18.930 に答える
0

科学計算の場合は、 Armadilloなどの専用の C++ 行列ライブラリを使用する方がはるかに優れています。これにより、配列処理が高速になるだけでなく、完全にデバッグされた多くの線形代数操作も可能になります。

パフォーマンス上の理由とは別に、専用の C++ マトリックス ライブラリを使用すると、コードの冗長性を大幅に削減し、間違いを減らし、開発をスピードアップすることもできます。1 つの例は、C++ マトリックス ライブラリを使用すると、メモリ管理について心配する必要がないことです。

最後に、本当に低レベルに移行する必要がある場合 (つまり、ポインターを介してメモリを直接使用する必要がある場合)、C++ では C レベルに "ドロップ" できます。Armadillo では、これは.memptr()メンバー関数を介して行われます。

于 2013-08-21T03:20:32.370 に答える