異なるコンパイラで最適化すると浮動小数点の結果が異なるのはなぜですか?

Susan Sarandon
リリース: 2024-11-11 00:10:03
オリジナル
917 人が閲覧しました

Why Do Floating-Point Results Differ With Optimization in Different Compilers?

最適化による浮動小数点の結果の相違: コンパイラのバグまたは予期される動作?

提供されたコード スニペットは、異なるコンパイラで最適化を使用した場合の浮動小数点計算結果の不一致を示しています。 。 Visual Studio 2008 および最適化なしの g では、コードは期待どおりの出力を生成します。ただし、g 最適化を有効にすると (O1 ~ O3)、誤った結果が表示されます。

Intel x86 プロセッサーの内部精度

この動作の根本原因を理解するには、Intel の次の点に注意することが重要です。 x86 プロセッサは、80 ビットの拡張精度を使用して内部で浮動小数点計算を処理します。対照的に、C の double データ型の幅は通常 64 ビットです。

最適化と浮動小数点ストレージ

最適化レベルは、CPU からの浮動小数点値がどのくらいの頻度で格納されるかに影響します。メモリ。これにより、値を保存中に 80 ビット精度から 64 ビット精度に変換するときに丸め誤差が発生する可能性があります。

問題の解決

最適化レベル全体で一貫した浮動小数点の結果を保証するには、gcc -ffloat-store オプションを提供します。このオプションを使用すると、浮動小数点値が常にメモリに格納され、レジスタの格納によって発生する丸めエラーが防止されます。

代わりに、gcc では通常 80 ビットの幅を持つ long double データ型を使用します。

VS2008 vs. g

ビジュアルが興味深いですね。 Studio 2008 では、拡張浮動小数点精度が有効になっている場合でも、正しい結果が得られます。これは、VS2008 が丸めと最適化を g とは異なる方法で処理することを示唆しています。

-ffloat-store の使用: 推奨プラクティス

-ffloat-store を使用することは厳密には必要ありませんが、ターゲットを指定する場合には使用することをお勧めします。内部で拡張浮動小数点精度を使用して、最適化レベル全体で予測可能な動作を保証するシステム。

追加考慮事項

x86_64 ビルドの場合、コンパイラはデフォルトで float と double に SSE レジスタを使用し、拡張精度の使用を排除するため、この問題は発生しません。 gcc コンパイラ オプション -mfpmath を使用すると、この動作を制御できます。

以上が異なるコンパイラで最適化すると浮動小数点の結果が異なるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート