質問
GCC のさまざまな最適化レベルの違いは何ですか?デバッグフックを使用する必要がないと仮定すると、利用可能な最高レベルの最適化を使用しないのはなぜでしょうか?必然的により高いレベルの最適化が行われます(つまり、おそらく)より高速なプログラムを生成できるでしょうか?
解決
はい、レベルが高いほど、プログラムのパフォーマンスが向上する場合があります。ただし、コードによっては問題が発生する可能性があります。たとえば、分岐予測 (-O1 以降で有効) は、競合状態を引き起こして、不適切に作成されたマルチスレッド プログラムを破壊する可能性があります。最適化によって実際には、作成した内容よりも優れたものが決定されますが、場合によっては機能しない可能性があります。
また、場合によっては、より高度な最適化 (-O3) を行うと、合理的なメリットが得られず、サイズが大幅に増加することがあります。このサイズのトレードオフがシステムのパフォーマンスを適切に向上させるかどうかは、独自のテストで判断できます。
最後に、GNU プロジェクトはすべてのプログラムを次の場所でコンパイルします。 デフォルトでは -O2, 、-O2 は他の場所ではかなり一般的です。
他のヒント
一般に、最適化レベルは以下よりも高くなります。 -O2
(ただ -O3
gcc 用ではありますが、他のコンパイラにはより高いコンパイラもあります)には、コードのサイズを増加させる可能性のある最適化が含まれています。これには、ループの展開、大量のインライン展開、サイズに関係なく位置合わせのためのパディングなどが含まれます。他のコンパイラは、より高いレベルでベクトル化とプロシージャ間の最適化を提供します。 -O3
, 同様に、正確性を犠牲にして速度を大幅に改善できる特定の最適化 (高速で精度の低い数学ルーチンの使用など) も含まれます。これらのものを使用する前にドキュメントを確認してください。
パフォーマンスに関してはトレードオフです。一般に、コンパイラ設計者は、コードのパフォーマンスが低下しないようにこれらを調整しようとします。 -O3
通常は(少なくとも私の経験では)役に立ちますが、実際の効果は人によって異なる場合があります。実際に積極的にサイズを変更する最適化によってパフォーマンスが向上するとは限りません (例:非常に積極的なインライン展開はキャッシュ汚染を引き起こす可能性があります)。
見つけました ウェブページ さまざまな最適化レベルに関する情報が含まれています。最適化によって実際にプログラムが壊れる可能性があり、それが問題になる可能性があるということは、どこかで聞いたことがあると思います。しかし、それがもはやどの程度の問題なのかはわかりません。おそらく、今日のコンパイラーは、これらの問題を処理できるほど賢くなっているのでしょう。
サイドノート:
世界的にどのようなフラグがオンになっているかを正確に予測するのは非常に困難です -O
gcc コマンド ラインのディレクティブはさまざまなバージョンやプラットフォームに対応しており、GCC サイトのすべてのドキュメントはすぐに古くなってしまう可能性が高く、コンパイラーの内部機能について十分に詳しく説明されていない可能性があります。
以下の簡単な方法で、次のいずれかを使用したときに特定のセットアップで何が起こるかを正確に確認できます。 -O
旗やその他 -f
フラグおよび/またはその組み合わせ:
- 空のソース ファイルをどこかに作成します。
touch dummy.c
- 通常と同じようにコンパイラ パスを介して実行します。
-O
,-f
および/または-m
通常使用するフラグですが、追加する-Q -v
コマンドラインに:gcc -c -Q -v dummy.c
- 生成された出力を検査し、別の実行のために保存することもあります。
- コマンドラインを好みに合わせて変更し、生成されたオブジェクトファイルを次のように削除します。
rm -f dummy.o
そして再実行します。
また、純粋主義の観点から、ほとんどの非自明な最適化では「壊れた」コードが生成されることを常に念頭に置いてください (ここで、壊れとは特殊なケースで最適なパスから逸脱することと定義されます)。一連の最適化メカニズムは、場合によっては、コンパイラー出力の正確性レベルの選択に要約されることがあります。どのコンパイラーのオプティマイザーにもバグは常に存在します (そして現在も存在します)。GCC メーリング リストと Bugzilla でいくつかのサンプルを確認してください。コンパイラの最適化は、実際に測定を実行した後にのみ使用してください。
- より優れたアルゴリズムを使用することによって得られる利益は、コンパイラの最適化によって得られる利益を小さくしてしまいます。
- 定期的に実行されるコードを最適化することに意味はありません。
- オプティマイザーによってバグが導入された場合、コードがどれだけ速く実行されるかは重要ではありません。