web-dev-qa-db-ja.com

Visual Studioで「コードの最適化」オプションは実際何をしますか?

オプションの名前は何かを伝えますが、Visual Studio /コンパイラは実際に何をし、実際の結果は何ですか?

編集:グーグルを検索すると このアドレス を見つけることができますが、それは私が探しているわけではありません。本当のことが起こっているのだろうか。たとえば、なぜループの時間が短くなるのかなど。

72
spinodal

最適化を行わないと、コンパイラは非常に馬鹿げたコードを生成します。各コマンドは非常に簡単な方法でコンパイルされるため、意図したとおりに動作します。デバッグビルドでは、最適化がデフォルトで無効になっています。これは、最適化なしでは、生成された実行可能ファイルがソースコードと簡単に一致するためです。

レジスタに保持される変数

最適化をオンにすると、コンパイラーは多くの異なる手法を適用して、同じことを実行しながらコードを高速に実行します。 Visual C++での最適化ビルドと非最適化ビルドの最も明らかな違いは、変数値が最適化ビルドで可能な限りレジスタに保持されるという事実と、最適化なしでは常にメモリに格納されるということです。これは、コードの速度だけでなく、デバッグにも影響します。この最適化の結果、デバッガーは、コードをステップ実行するときに変数値を確実に取得できません。

その他の最適化

/ Oオプション(コードの最適化)MSDNドキュメント で説明されているように、コンパイラーによって適用される他の複数の最適化があります。さまざまな最適化手法の一般的な説明については、 Wikipedia Compiler Optimization article を参照してください。

59
Suma

Paul Vick's ブログから:

  • デバッグを支援するために発行するNOP命令を削除します。最適化がオフになっている(およびデバッグ情報がオンになっている)場合、コンパイラーは、実際のILが関連付けられていないがブレークポイントを配置したい行に対してNOP命令を発行します。このようなものの最も一般的な例は、「If」ステートメントの「End If」です。EndIfに対して実際のILは発行されないため、NOPを発行しないため、デバッガーはブレークポイントを設定できません。その上。最適化をオンにすると、コンパイラーはNOPを発行しなくなります。

  • 生成されたILの単純な基本ブロック分析を行い、デッドコードブロックを削除します。つまり、各メソッドを、分岐命令で区切られたILのブロックに分割します。ブロックの相互関係をすばやく分析することで、分岐のないブロックを特定できます。したがって、決して実行されず、省略できるコードブロックを見つけて、アセンブリをわずかに小さくすることができます。また、この時点でいくつかのマイナーブランチの最適化も行います。たとえば、別のGoToステートメントにGoToする場合、最初のGoToを最適化して2番目のGoToのターゲットにジャンプします。

  • IsJITOptimizerDisabledをFalseに設定してDebuggableAttributeを発行します。基本的に、これにより、ランタイムJITはコードの並べ替えやインライン化など、コードの適合性を最適化できます。これにより、より効率的で小さなコードが生成されますが、コードをデバッグしようとするのは非常に難しい場合があります(試した人なら誰でもわかるように)。 JIT最適化の実際のリストは私が知らないものです-Chris Brummeのような誰かがこれについてのある時点で口にするでしょう。長所と短所は、最適化スイッチが最適化を有効にし、ブレークポイントの設定とコードのステップ実行を困難にする可能性があることです。

16
reva

簡単な答えは次のとおりです。-Oxを使用し、コンパイラに任せます。

長い答え:さまざまな種類の最適化の効果を正確に予測することは不可能です。場合によっては、高速コード用に最適化すると、サイズ用に最適化する場合よりも実際に小さいコードが生成される場合があります。パフォーマンスの最後の0.01%(速度またはサイズ)を本当に取得したい場合は、さまざまなオプションの組み合わせをベンチマークする必要があります。

また、最近のバージョンのVisual Studioには、リンク時最適化やプロファイルに基づく最適化など、より高度な最適化のためのオプションがあります。

2
JesperE