g++ で最適化レベル -O3 は危険ですか? 質問する

g++ で最適化レベル -O3 は危険ですか? 質問する

さまざまな情報源から(ほとんどは同僚からだが)、-O3g++ で最適化レベル でコンパイルするのはどういうわけか「危険」であり、必要であることが証明されない限りは一般的に避けるべきだと聞いている。

これは本当ですか? もし本当なら、なぜですか? 私はただ に固執するべきでしょうか-O2?

ベストアンサー1

gcc の初期の頃 (2.8 など) や egcs、redhat 2.96 の時代には、-O3 は時々かなりバグが多かったです。しかし、これは 10 年以上前の話で、-O3 は他のレベルの最適化と (バグの多さという点では) あまり変わりません。

ただし、言語のルール、特にコーナーケースに厳密に依存しているため、未定義の動作に依存しているケースが明らかになる傾向があります。

個人的な意見ですが、私は金融部門で長年 -O3 を使用して実稼働ソフトウェアを実行していますが、-O2 を使用していた場合には発生しなかったバグにはまだ遭遇していません。

多くの要望により、ここに追加します:

-O3 および特に -funroll-loops などの追加フラグ (-O3 では有効にならない) によって、生成されるマシン コードが増えることがあります。特定の状況 (L1 命令キャッシュが非常に小さい CPU など) では、たとえば内部ループのコード全体が L1I に収まらなくなるため、速度が低下することがあります。通常、gcc は大量のコードを生成しないようにかなり努力しますが、通常は一般的なケースを最適化するため、これが発生する可能性があります。特にこの傾向が強いオプション (ループ アンローリングなど) は通常 -O3 には含まれておらず、man ページでそのようにマークされています。そのため、高速コードを生成するには -O3 を使用し、適切な場合 (プロファイラーが L1I ミスを示した場合など) にのみ -O2 または -Os (コード サイズの最適化を試みる) にフォールバックするのが一般的には良い考えです。

最適化を極限まで進めたい場合は、--param を使用して gcc で特定の最適化に関連するコストを微調整できます。また、gcc には、これらの関数のみの最適化設定を制御する属性を関数に配置する機能が追加されました。そのため、1 つの関数で -O3 に問題があることがわかった場合 (またはその関数のみに特別なフラグを試したい場合)、ファイル全体、さらにはプロジェクト全体を O2 でコンパイルする必要はありません。

一方、-Ofast を使用する場合は注意が必要であるようです。

-Ofast は、すべての -O3 最適化を有効にします。また、すべての標準準拠プログラムに有効ではない最適化も有効にします。

これにより、-O3 は完全に標準に準拠するように意図されているという結論に達しました。

おすすめ記事