27

STL コンテナーを使用すると、コードのデバッグ バージョンの実行が非常に遅くなるため、STL コンテナーを使用するのは本当に嫌いです。デバッグ ビルドで妥当なパフォーマンスを発揮する STL の代わりに、他の人は何を使用していますか?

私はゲーム プログラマーですが、これは私が取り組んできた多くのプロジェクトで問題になっています。すべてに STL コンテナーを使用すると、60 fps を取得するのはかなり困難です。

私はほとんどの作業で MSVC を使用しています。

4

15 に答える 15

25

EASTL は可能ですが、まだ完全ではありません。Electronic Arts の Paul Pedriana は、ゲーム アプリケーションのパフォーマンスに関して、さまざまな STL 実装の調査を行いました 。 /n2271.html

これらの調整の一部は、C++ 標準に含めるために検討されています。

また、EASTL でさえ、最適化されていないケースでは最適化されないことに注意してください。少し前のタイミングでExcelファイルを持っていましたが、紛失したと思いますが、アクセスするには次のようなものでした:

       debug   release
STL      100        10
EASTL     10         3
array[i]   3         1

私が経験した中で最も成功したのは、独自のコンテナーを展開したことです。これらを array[x] のパフォーマンスに近づけることができます。

于 2008-09-17T20:38:24.047 に答える
21

私の経験では、オプティマイザーがオフになっているため、適切に設計された STL コードはデバッグ ビルドでの実行が遅くなります。STL コンテナーは、リリース ビルドでインライン化/削除される (軽量の場合) コンストラクターと operator= への多くの呼び出しを発行します。

また、Visual C++ 2005 以降では、リリース ビルドとデバッグ ビルドの両方で STL のチェックが有効になっています。これは、STL を多用するソフトウェアのパフォーマンスを大幅に浪費します。すべてのコンパイル単位に対して _SECURE_SCL=0 を定義することで無効にできます。異なるコンパイル単位で異なる _SECURE_SCL ステータスを持つことは、ほぼ確実に災害に​​つながることに注意してください。

チェックをオフにして 3 番目のビルド構成を作成し、それを使用してパフォーマンスを向上させることができます。ただし、エラーのある配列インデックスなどをキャッチするのに非常に役立つため、チェックをオンにしてデバッグ構成を維持することをお勧めします。

于 2008-09-17T20:37:16.653 に答える
10

ビジュアル スタジオを実行している場合は、次の点を考慮する必要があります。

#define _SECURE_SCL 0
#define _HAS_ITERATOR_DEBUGGING 0

それはイテレータだけです。どのタイプの STL 操作を実行していますか? メモリ操作の最適化を検討することをお勧めします。つまり、一度に 1 つずつ要素を挿入するために pop/push を使用する代わりに、resize() を使用して一度に複数の要素を挿入します。

于 2008-09-17T20:27:48.860 に答える
7

大規模でパフォーマンスが重要なアプリケーションの場合、ニーズに合わせて特別に調整された独自のコンテナーを構築することは、時間の投資に値する場合があります。

ここでは実際のゲーム開発について話しています。

于 2008-09-17T20:39:07.303 に答える
4

Visual C++ を使用している場合は、次を参照してください。

http://channel9.msdn.com/shows/Going+Deep/STL-Iterator-Debugging-and-Secure-SCL/

MS/Dinkware STL が行うすべてのデバッグ モード チェックのさまざまなコストとオプションをカバーする、そのページのリンク。

このようなプラットフォームに依存する質問をする場合は、プラットフォームについても言及することをお勧めします...

于 2008-09-17T20:16:05.893 に答える
4

あなたの STL は、デバッグ用にチェック済みの実装を使用していると思います。イテレータのオーバーランなどをキャッチするので、これはおそらく良いことです。それがそれほど問題である場合は、それをオフにするコンパイラ スイッチがある可能性があります。ドキュメントを確認してください。

于 2008-09-17T20:11:20.880 に答える
3

EASTLをチェックしてください。

于 2008-09-17T20:20:25.837 に答える
3

申し訳ありませんが、コメントを残すことができないので、ここに答えがあります: EASTL は github で利用できるようになりました: https://github.com/paulhodge/EASTL

于 2011-01-15T01:50:11.453 に答える
3

MSVC はデバッグ ビルドでチェック済み反復子の非常に重い実装を使用しますが、これについては他の人が既に説明しているため、繰り返しません (ただし、そこから始めます)。

あなたにとって興味深いかもしれないもう 1 つのことは、「デバッグ ビルド」と「リリース ビルド」には、おそらく大まかにしか関連しない 4 つの設定の変更が含まれることです。

  1. シンボリック デバッグを可能にする .pdb ファイル (cl /Zi および link /DEBUG) を生成します。/OPT:ref をリンカー オプションに追加することもできます。リンカーは、.pdb ファイルを作成しない場合、参照されていない関数を削除しますが、明示的に追加しない限り、/DEBUG モードではすべての関数を保持します (デバッグ シンボルがそれらを参照するため)。
  2. C ランタイム ライブラリのデバッグ バージョンを使用します (おそらく MSVCR*D.dll ですが、使用しているランタイムによって異なります)。これは、/MT または /MTd (または、dll ランタイムを使用していない場合は他の何か) に要約されます。
  3. コンパイラの最適化をオフにする (/Od)
  4. プリプロセッサの設定 #define DEBUG または NDEBUG

これらは独立して切り替えることができます。1 つ目は、サイズは増えますが、実行時のパフォーマンスには何の影響もありません。2 番目は多くの関数をより高価にしますが、malloc と free に大きな影響を与えます。デバッグ ランタイム バージョンは、初期化されていないデータのバグを明確にするために、値で接触するメモリを「汚染」するように注意しています。MSVCP* STL 実装では、通常行われるすべての割り当てプーリングも排除されるため、リークは、サブ割り当てされているメモリの大きなチャンクではなく、考えられるブロックを正確に示します。つまり、malloc の呼び出しが多くなる上に、はるかに遅くなります。第3; まあ、それはたくさんのことをします(この質問主題についていくつかの良い議論があります)。残念ながら、シングルステップをスムーズに動作させるには、これが必要です。4 番目は、さまざまな方法で多くのライブラリに影響を与えますが、最も注目すべきは、assert() およびその仲間をコンパイルまたは削除することです。

したがって、これらの選択肢の組み合わせを少なくしてビルドを作成することを検討してください。私はシンボル (/Zi とリンク /DEBUG) とアサート (/DDEBUG) を使用するビルドをよく使用しますが、最適化されています (/O1 または /O2 または使用するフラグ)。バックトレースをクリア (/Oy-) し、通常のランタイム ライブラリ (/MT) を使用します。これは私のリリース ビルドに近いパフォーマンスを発揮し、ある程度デバッグ可能です (バックトレースは問題なく、シングル ステップはソース レベルでは少し奇抜ですが、アセンブリ レベルはもちろん問題なく動作します)。必要な数の構成を持つことができます。リリース 1 のクローンを作成し、デバッグの有用な部分をオンにするだけです。

于 2008-09-18T02:50:56.333 に答える
1

Ultimate++ には独自のコンテナ セットがあります。ライブラリの残りの部分とは別に使用できるかどうかはわかりません: http://www.ultimatepp.org/

于 2008-09-17T20:25:34.717 に答える
1

Qtは、ほとんどの C++ 標準ライブラリを異なるインターフェイスで再実装しました。見た目はかなり良いですが、商用ライセンス版の場合は高価になる可能性があります.

編集: Qt はその後LGPLの下でリリースされました。これにより、通常、商用バージョン (まだ存在します) を使わずに商用製品で使用することができます。

于 2008-09-18T13:56:06.500 に答える
1

ACE ライブラリはどうですか? これは同時通信ソフトウェア用のオープンソースのオブジェクト指向フレームワークですが、いくつかのコンテナー クラスもあります。

于 2008-09-17T20:37:02.177 に答える
1

Bruno Preiss による C++ のオブジェクト指向設計パターンを使用したチェックアウト データ構造とアルゴリズム http://www.brpreiss.com/

于 2008-09-17T20:58:26.727 に答える
0

STL コンテナは、デバッグ中やその他の場所で「非常にゆっくり」実行するべきではありません。おそらく、あなたはそれらを悪用しています。デバッグで ElectricFence や Valgrind などに対して実行していませんか? 多くの割り当てを行うものはすべて遅くなります。

すべてのコンテナーはカスタム アロケーターを使用できます。これは、パフォーマンスを向上させるために使用する人もいますが、自分で使用する必要はありませんでした。

于 2008-09-17T20:11:51.987 に答える