コンパイラ (GCC) によって行われる最適化に関して、標準的な方法は何ですか? 各オプション (-O、-O1、-O2、-O3、-Os、-s、-fexpensive-optimizations) の違いは何ですか? また、何が最適かを判断するにはどうすればよいですか?
2 に答える
通常、-O2 は最初に試すのに適した最適化レベルです。
ただし、可能な限り最高の結果が必要な場合は、アプリに最適なレベルを事前に判断できないため、多くの最適化レベルを試すことになります。
また、最適化の結果は CPU ごとに異なることに注意してください (一部の CPU では、サイズを最適化すると、実際には速度を最適化するよりも速度が向上する場合があります)。
今後の参考のために、各レベルの簡単な説明を次に示します (完全な説明は、ドキュメントhttp://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.htmlにあります)。
-O (-O1 と同じ): -O を指定すると、コンパイラは、コンパイルに多大な時間を要する最適化を実行せずに、コード サイズと実行時間を削減しようとします。
-O2: さらに最適化します。GCC は、容量と速度のトレードオフを含まない、サポートされているほぼすべての最適化を実行します。-O と比較して、このオプションはコンパイル時間と生成されたコードのパフォーマンスの両方を向上させます。
-O3: さらに最適化します。-O3 は、-O2 で指定されたすべての最適化をオンにし、-finline-functions、-funswitch-loops、-fpredictive-commoning、-fgcse-after-reload、-ftree-vectorize、-ftree-partial-pre および - もオンにします。 fipa-cp-clone オプション。
-Os: サイズを最適化します。-Os は、通常はコード サイズを増加させないすべての -O2 最適化を有効にします。また、コード サイズを削減するために設計されたさらなる最適化も実行します。
-Ofast: 厳密な標準準拠を無視します。-Ofast は、すべての -O3 最適化を有効にします。また、すべての標準準拠プログラムに有効ではない最適化も有効にします。-ffast-math と Fortran 固有の -fno-protect-parens および -fstack-arrays をオンにします。レベル番号の有無にかかわらず、複数の -O オプションを使用すると、最後のオプションが有効になります。
Linux カーネルMakefile
は と の両方-O2
を提供します-Os
。詳細が不足している場合は、どちらかが適切です。
は-Os
、小さなストレージ用に最適化します。最近の CPU はメイン メモリよりもはるかに高速であるため、小さなストレージ用に最適化することは巨大なマシンでも理にかなっています。したがって、スペース効率のためにコンパイルして命令キャッシュを最大限に活用してください。実行時間も改善される可能性があります。
すべての-O2
「通常の最適化」が実行され、選択された最適化は安全になります。(一部の最適化は常に安全であるとは限らないと聞いてい-O3
ますが、それは、Linux カーネルが通常のアプリケーションには一般的ではないいくつかの制約の下で実行されるためかもしれません。)
もちろん、最良の答えは、複数レベルの最適化を使用してソフトウェアをコンパイルすることです。ソフトウェアのコンパイルにかかる時間と、ソフトウェアが代表的なベンチマーク テストを実行するのにかかる時間。それらすべてに使用されているメモリ量を測定します。
次に、コンパイル速度、実行時の速度、および実行時のメモリ使用量の「最適な」組み合わせを選択します。最速のコンパイルが必要な場合や、最速の実行時間が必要な場合、またはお金を節約するために仮想ホスティング プロバイダーの少量のメモリに収まるようにしようとしている場合があります。
-O2
測定を行わずに選択するのはおそらく公平です。