Gccの--ffast-math
フラグを使用すると、フロート操作の速度が大幅に向上し、IEEE標準の範囲外になりますが、実際に何が起こっているのかについての情報を見つけることができません。誰かが詳細のいくつかを説明してください、そしておそらくフラグがオンまたはオフだった場合に何かがどのように変化するかについて明確な例を与えることができますか?
私はS.Oを掘ってみました同様の質問ですが、ffast-mathの動作を説明するものが見つかりませんでした。
前述のように、厳密なIEEE準拠を維持しない最適化が可能です。
例は次のとおりです。
x = x*x*x*x*x*x*x*x;
に
x *= x;
x *= x;
x *= x;
浮動小数点演算は結合的ではないため、演算の順序付けと因数分解は丸めのために結果に影響します。したがって、この最適化は厳密なFP動作の下では行われません。
GCCが実際にこの特定の最適化を行うかどうかを実際に確認したことはありません。しかし、考え方は同じです。
-ffast-math
は、厳密なIEEE準拠を破るだけではありません。
もちろん、まず第一に、それは破損する厳密なIEEE準拠です。数学的には(理想的には)数学的には同じですが、浮動小数点ではまったく同じではないものへの命令の並べ替え。
第二に、それはdisables単一命令数学関数の後にerrno
を設定します。これは、スレッドローカル変数への書き込みを回避することを意味します(これにより、一部のアーキテクチャでこれらの関数が100% )。
3番目に、すべての数学は有限であると仮定します。これは、有害な影響がある場所ではNaN(またはゼロ)のチェックが行われないことを意味します。これは起こらないと単純に想定されています。
4番目に、除算および逆平方根に対して逆近似を有効にします。
さらに、符号付きゼロ(ターゲットがそれをサポートしていても符号付きゼロが存在しないことを前提とするコード)および丸め数学を無効にします。これにより、特にコンパイル時の定数の折りたたみが可能になります。
最後に、シグナル/トラップの数学のためにハードウェア割り込みが発生しないことを前提とするコードを生成します(つまり、ターゲットアーキテクチャでこれらを無効にできないため、結果としてdo発生、処理されません) 。