[解決済み] O3/Ofastを超えるG++の最適化
質問
問題点
あるシミュレーションタスクの中規模プログラムがあり、それを最適化する必要があります。私たちはすでに、プログラミング スキルの限界までソースを最適化することに全力を尽くしてきました。 Gprof と Valgrind .
最終的に完成したら、おそらく数カ月間、いくつかのシステムでプログラムを実行したいと思います。したがって、私たちは、最適化を限界まで推し進めることに本当に興味があります。
すべてのシステムは、比較的新しいハードウェア (Intel i5 または i7) 上で Debian/Linux を実行する予定です。
質問事項
g++ の最近のバージョンを使用して、-O3/-Ofast を超える最適化オプションは何が可能ですか?
私たちはまた、長期的に利益をもたらす、コストのかかるマイナーな最適化に興味があります。
強いて言えば
今使っているもの
現在、以下のg++の最適化オプションを使用しています。
-
-Ofast
: 最高水準の最適化レベル。含まれる-ffast-math
は、私たちの計算では何の問題も引き起こさないので、標準に準拠していないにもかかわらず、それを採用することにしました。 -
-march=native
: すべての CPU 固有の命令を使用できるようにします。 -
-flto
を使用して、異なるコンパイル単位にまたがるリンク時の最適化を可能にします。
どのように解決するのですか?
ほとんどの回答は、別のコンパイラや外部ライブラリなど、おそらく多くの書き換えや統合作業をもたらすであろう代替の解決策を提案しています。私は、質問の内容に固執し、OP が要求したように、コンパイラー フラグを有効にするか、コードに最小限の変更を行うことによって、GCC 単独で何ができるかに焦点を当てようとします。これは、「こうしなければならない」という回答ではなく、私自身にとってうまくいったGCCの微調整のコレクションであり、あなたの特定のコンテキストに関連するものであれば、試してみることができるものです。
元の質問に関する警告
詳細に入る前に、質問に関するいくつかの警告があります。典型的には、質問を読んで、「OPはO3を超えて最適化している。
-
-march=native
は 命令を使用できるようになります。 を使用することができます。異なる CPU を持つシステムで実行すると、プログラムが全く動作しないか、著しく遅くなる可能性があります(これはmtune=native
も有効になるため)、使用する場合はこの点に注意してください。詳細情報 はこちら . -
-Ofast
のように、いくつかの 非標準準拠の を最適化することができますので、使用には注意が必要です。詳細はこちら はこちら .
試してみたい他のGCCフラグ
異なるフラグの詳細は以下のとおりです。 はこちら .
-
-Ofast
可能にする-ffast-math
を有効にし、その結果-fno-math-errno
,-funsafe-math-optimizations
,-ffinite-math-only
,-fno-rounding-math
,-fno-signaling-nans
と-fcx-limited-range
. さらに進んで 浮動小数点演算の最適化 を選択的に追加することで 追加フラグ 例えば-fno-signed-zeros
,-fno-trapping-math
などがあります。これらは-Ofast
に含まれておらず、計算のパフォーマンスをさらに向上させることができますが、実際に恩恵があるかどうか、計算を壊さないかどうかをチェックする必要があります。 -
GCCはまた、大量の
他の最適化フラグ
これらはどの "-O" オプションでも有効になりません。それらは "壊れたコードを生成する可能性のある実験的なオプションとしてリストされています。とはいえ、私はしばしば
-frename-registers
このオプションは私にとって望ましくない結果をもたらしたことはなく、顕著な性能向上(つまり、ベンチマークで測定可能)をもたらす傾向があります。これは、プロセッサに大きく依存するタイプのフラグですが。-funroll-loops
も良い結果をもたらすことがあります(また、暗黙のうちに-frename-registers
を意味します) が、それは実際のコードに依存します。
PGO
GCCは プロファイル誘導型最適化 機能を備えています。これに関する正確なGCCドキュメントはあまりありませんが、それでもこれを実行するのは非常に簡単です。
-
であなたのプログラムをコンパイルします。
-fprofile-generate
. - を実行します (コードはプロファイル情報を .gcda ファイルに生成しているため、実行時間は大幅に遅くなります)。
-
を使用してプログラムを再コンパイルします。
-fprofile-use
. アプリケーションがマルチスレッドである場合は、コンパイル時に-fprofile-correction
フラグを追加します。
GCC での PGO は驚くべき結果をもたらし、本当に大幅にパフォーマンスを向上させます (私が最近取り組んでいたプロジェクトの 1 つでは、15 ~ 20% の速度向上が見られました)。明らかに、ここでの問題は、いくつかの データを十分に代表する これは、常に利用可能とは限りませんし、入手するのも簡単ではありません。
GCCの並列モード
GCCの特徴は 並列モード これは、GCC 4.2 コンパイラがリリースされた頃に初めてリリースされました。
基本的に、これは以下のものを提供します。
C++ 標準ライブラリにある多くのアルゴリズムの並列実装を提供します。
. これらをグローバルに有効にするには、単に
-fopenmp
と
-D_GLIBCXX_PARALLEL
フラグをコンパイラに渡します。また、必要に応じて各アルゴリズムを選択的に有効にすることもできますが、その場合は若干のコード変更が必要になります。
この並列モードに関するすべての情報は、以下のサイトで見ることができます。 を参照してください。 .
大きなデータ構造でこれらのアルゴリズムを頻繁に使用し、多くのハードウェアスレッドコンテキストが利用できる場合、これらの並列実装は大きなパフォーマンスブーストを与えることができます。私が利用した並列実装は
sort
の並列実装しか使用していませんが、おおよその見当をつけるために、私のアプリケーションの 1 つでソートの時間を 14 秒から 4 秒に減らすことができました (テスト環境: カスタム コンパレータ関数と 8 コアのマシンによる 1 億個のオブジェクトのベクトル)。
その他のトリック
これまでのポイント編とは異なり、このパートでは はコードの小さな変更を必要とします。 . また、それらはGCCに特有なので(いくつかはClangでも動作します)、他のコンパイラでコードの移植性を保つために、コンパイル時のマクロを使用する必要があります。このセクションはより高度なテクニックを含んでおり、何が起こっているのかをアセンブリレベルで理解していない場合は使用しないでください。また、最近のプロセッサーやコンパイラーはかなり賢いので、ここで説明する機能から顕著な利益を得るのは難しいかもしれないことに注意してください。
-
GCC ビルトイン、これはリストされています
ここに
. のようなコンストラクタは
__builtin_expect
を提供することで、コンパイラがより良い最適化を行うのを助けることができます。 分岐予測 の情報を提供することで、コンパイラがより良い最適化を行えるようにします。その他の構成要素である__builtin_prefetch
などの構成は、アクセスされる前にデータをキャッシュに取り込みます。 キャッシュミス . -
関数属性の一覧です。
ここに
. 特に
hot
とcold
属性があります。前者はコンパイラにその関数が ホットスポット であることをコンパイラに示し、より積極的に関数を最適化し、テキストセクションの特別なサブセクションに配置し、より良いローカリティを実現します。
この回答が一部の開発者にとって有用であることを望みます。また、編集や提案を喜んで検討させていただきます。
関連
-
[解決済み】構造体のベクター初期化について
-
[解決済み】C++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み】C++エラー:の初期化に一致するコンストラクタがありません。
-
[解決済み】c++でstd::vectorを返すための効率的な方法
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】演算子のオーバーロード C++; <<操作のパラメータが多すぎる
-
[解決済み] コピーエリジョンと戻り値の最適化とは何ですか?
-
[解決済み] インテル Sandybridge ファミリー CPU のパイプラインのためのプログラムの最適化解除
-
[解決済み] スタックサンプリングの先にあるもの。C++プロファイラ
-
[解決済み] Clangの最適化レベル
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 unsigned int vs. size_t
-
[解決済み] テスト
-
[解決済み】Visual Studio 2015で「非標準の構文; '&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み] エラーが発生する。ISO C++は型を持たない宣言を禁じています。
-
[解決済み】抽象クラス型の無効なnew-expression
-
[解決済み】関数名の前に期待されるイニシャライザー
-
[解決済み】クラステンプレートの使用にはテンプレート引数リストが必要です
-
[解決済み】エラー:free(): 次のサイズが無効です(fast)。
-
[解決済み】エラー。引数リストに一致するコンストラクタのインスタンスがない
-
[解決済み】c++で.txtファイルから2次元の配列に読み込む