3

私は先週、再帰的なBranch&CutアルゴリズムをMatlabからC ++に移植することに費やし、ソリューション時間の大幅な短縮を期待していましたが、信じられないほどのことですが、その逆でした。今はC++の専門家ではないので、眠そうなプロファイラーをダウンロードして、潜在的なボトルネックを見つけようとしました。私はこれから正しい結論を引き出しているのか、それとも完全に間違った方向を見ているのかを尋ねたいと思います。

コードを137秒間実行します。これは、プロファイラーが表示するものです(以下の他の多くのエントリですが、重要ではありません)。

ここに画像の説明を入力してください

したがって、これを正しく行うと、98秒が新しいオブジェクトの作成に費やされ、34秒がメモリの解放(つまりオブジェクトの削除)に費やされました。

私は自分のコードを調べて、どこでもっとうまくやれるかを調べますが、そのような振る舞いを引き起こす頻繁な間違いや悪い習慣についてのヒントがあるかどうかも尋ねたいと思いました。私の頭に浮かぶことの1つは、コードで多くの一時的なstd :: vectorを使用して計算を行うため、処理が遅くなる可能性があることです。

あなたが盲目になるのを防ぐために、私は少し調べる前にコードを投稿しませんが、これを自分で解決できない場合は戻ってきます。

4

4 に答える 4

5

はい、std::vector誤用すると高くつく可能性があります。最大のパフォーマンス ヒットは再割り当てである可能性があります。サイズを動的に調整する必要があり、要素が連続メモリ内にある必要があるという制約があるため、既に割り当てられているものを超えて新しい要素を追加するたびに再割り当てが発生します。

そのため、事前にサイズを宣言する必要があります。n要素を保持する必要があることがわかっている場合は、次のように宣言します。

 std::vector<MyClass> x(n);

また

 std::vector<MyClass> x;
 x.reserve(n);

ただの代わりに

 std::vector<MyClass> x;

続いてnpush_backs。

この後もまだ遅い場合はstd::vector、カスタム アロケーターを提供できます。あなたがその点に達しないことを願っています。

于 2013-01-25T14:05:49.083 に答える
1

Matlab では、すべてがオブジェクトへの参照です。したがって、それらを渡すときは、おそらく大きさが大きい行列全体をコピーするのではなく、ポインター (いくつかの要因に応じてサイズが約 int) をコピーするのと同じことを行っています。

コードを見なければ、確かなことは言えませんが、オブジェクトへの参照をコピーするのではなく、大量のオブジェクトをコピーしていると思われます。などのスマート ポインターを調べることをお勧めしますstd::shared_ptr

明確にはしませんでしたが、最適化してコンパイルする必要があります。( g++ -O3.) 一部の高価なコピーやその他の操作は最適化できますが、すべてではありません。

さらに、C++ を初めて使用する場合は、new. これは専門家向けであり、同僚との議論と濃いコーヒーの後にのみ使用されます。(もちろん、newなどの一部のコンテナーでユーザーに代わって使用される場合がありますstd::vector。)

于 2013-01-25T14:05:46.047 に答える
0

Luchian Grigore が述べたように、 std::vector は高価です。しかしそれだけではなく、オブジェクトの作成、データの移動、メモリの再割り当て、さらにはメモリの削除さえも行うコードの部分は、時間がかかる可能性があります。アレックス・チェンバレンの言うことが本当なら、そこには大きなボトルネックがあります。そうでない場合は、ソフトウェアのメモリ消費量を削減するために行うほとんどすべてのことは、パフォーマンスで支払われることを思い出してください (または、ご存知ない場合は教えてください)。また、その逆も当てはまります。以前に計算されたすべてのキャッシュを作成するため、メモリ消費量が多いということは、CPU の計算量が少なくなることを意味します。基本的なことですが、時々忘れてしまいます。

于 2013-01-25T14:33:20.807 に答える
-1

タイムクリティカルなコードで new と delete を呼び出さないようにします。遅いです。または、高速メモリ マネージャ (SmartHeap など) を使用します。

于 2013-01-25T14:05:55.993 に答える