オプション-ffast-mathはどのような最適化を行いますか?

オプションを使用して、単純な$ O(n ^ 2)$アルゴリズムが$ O(n)$アルゴリズムのアルゴリズムに短縮されるまでにかかる時間。

コメント

回答

この質問に対する正規の回答がGCCのwikiにあります。おそらく維持されており、このタイプの質問の最も信頼できる情報源です。一方、この質問は最終的に古くなる可能性があります。これはすべて、例を使用してwikiで詳細に説明されています。本質的には、この正確な質問にどのように答えるかを説明するための引用であり、マイナーなコメントがあります:

  • -fno-signaling-nans
  • -fno-trapping-math

    IEEE標準では、実装でトラップハンドラーがexcを処理できるようにすることを推奨していますゼロ除算やオーバーフローなどのセプション。このフラグは、use-visibleトラップが発生しないことを前提としています。

  • -funsafe-math-optimizations -これらの最適化は、浮動小数点演算の法則に違反し、通常の無限精度の演算の法則に置き換わる可能性があります。

    丸め誤差のため、結合法則代数の法則は浮動小数点数に当てはまる必要はないため、(x + y)+ zのような式はx +(y + zに等しい)である必要はありません。

  • -ffinite-math-onlyinfnanは表示されないと想定されているため、それらを探して適切に処理するために費やす時間を節約できます。たとえば、$ x-x $は常に$ 0.0 $と等しくなければなりませんか?

  • -fno-errno-math

    数学ライブラリルーチンの呼び出し時に、C89 / C99で必要とされるerrno変数の設定を無効にします。 Fortranの場合、これがデフォルトです。

  • -fcx-limited-range

    複雑な除算を実行するときに、範囲縮小ステップが省略されます。これは$ a / b =((ar * br + ai * bi)/ t)+ i((ai * br –ar * bi)/ t)$を$ t = br * br + bi * bi $で使用します。入力の任意の範囲ではうまく機能しません。

  • -fno-rounding-math

  • -fno-signed-zeros

    丸め誤差のため、代数の結合法則は、浮動小数点数、つまり(x + y)+ zのような式は必ずしもx +(y + z)と等しい必要はありません。

厳密に言えば、最後の2つの意味は、思っているほど直感的であるとは限りません。たとえば(wikiを参照)、$-(a –a)= a –a $はどうですか、それは$ + 0.0 $または$ -0.0 $ですか?特に Bill Kahan による正確な影響についてはかなりの量の文献があると思います。

  • 直接言及されていません(I表示されませんか?)が、-ffast-mathを使用すると、逆数$ 1 / x $や平方根$ \ sqrt {x} $などの特定の一般的な特殊関数がlessに置き換えられます。より高速であるが、「許容できる」エラーレベルがまだある正確なバージョン(標準で要求される0ulpエラーに対して)-たとえば、ここでは、通常、精度が提供されます。 glibcのlibm 。確かに、これは-ffast-mathからのスピードアップの最も一般的な原因であり、除算と平方根を使用して多くの算術演算を行うコードで、ほぼ私が(個人的に / em>)他のサブオプション(-ffinite-math-onlyなど-特に-シグナリングNaNはデバッグに非常に役立ちます)も少し原因になると思いますコスト/メリットの点で非常に面倒です。

単純な$ O(n ^ 2)$に時間がかかることがわかりました。オプションを使用すると、アルゴリズムが$ O(n)$アルゴリズムのアルゴリズムに縮小されます。

これはありそうもないことであり、間違いを犯した可能性があります。あなたの分析で。安全でない浮動小数点最適化では、最適化の選択肢が増えるため、個々の式の評価がいくらか安くなる可能性があります。しかし、スピードアップは常にせいぜい一定の要因でなければなりません。 $ O(n ^ 2)$アルゴリズムを$ O(n)$と比較して、$ n $の大きさが不十分な場合は可能ですか?

回答

$ n ^ 2 $アルゴリズムは、たとえば$ n $がコンパイラーに認識されており、ベクトルサイズの倍数である場合、$ O(n)$で動作するものに減らすことができます。プロセッサでサポートされているベクトル命令(存在する場合)。コンパイラがこれらすべてを認識できる場合は、内部ループを展開し、ベクトル命令を使用して作業を行うことができます。これにより、実行される操作全体がほんの一握りに減り、パフォーマンスが大幅に向上する可能性があります。

私の読みでは、fast-mathはそのような最適化を有効にしませんが、unsafe-math-optimizationsそこで無効になっている結合制限のため。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です