を追加し、デフォルト-O3 -fma
が融合乗算GCC 5.3で丸めモード
float mul_add(float a, float b, float c) {
return a*b + c;
}
で次のコードcompieldは、次のアセンブリ
vfmadd132ss %xmm1, %xmm2, %xmm0
ret
I noticed GCC doing this with -O3
already in GCC 4.8を生成します。 -O3 -mfma
と
クラン3.7 -O3 fast
とGCCと同じコードを生成-Ofast -mfma
と
vmulss %xmm1, %xmm0, %xmm0
vaddss %xmm2, %xmm0, %xmm0
retq
なくクラン3.7を生成します。 this answerから、それはコンパイラが分離アドオンを融合し、あなたはリラックスした浮動小数点モデルを可能にしない限り、乗算することは許されない
言うので
私はGCCが
-O3
でないことを驚いています。これは、FMAには1回の丸めがあり、ADD + MULには2回の丸めがあるからです。したがって、コンパイラはfusingによって厳密なIEEE浮動小数点の動作に違反します。しかしながら
、this linkからは
言うかかわらずFLT_EVAL_METHODの値の任意の浮動小数点表現は、すべての中間結果は、無限の範囲及び精度を有しているかのように計算され、すなわち、縮小されてもよいです。
だから私は混乱して懸念しています。
- GCCはFMAを使用して
-O3
で正当化されていますか? - fusingは厳密なIEEE浮動小数点の動作に違反しますか?
- ヒューズがIEEE浮動小数点ビアビールに違反し、GCC returns
__STDC_IEC_559__
がこれと矛盾しないので、 FMA can be emulated in software以来
FMAための2つのコンパイラスイッチがあるはずであるように思わ:ハードウェアはFMAを持っているコンパイラに指示する計算と一つにFMAを使用するようにコンパイラに指示する1。
これは、オプション-ffp-contract
で制御できます。 GCCではデフォルトは-ffp-contract=fast
で、Clangではそうではありません。 -ffp-contract=on
と-ffp-contract=off
のような他のオプションは、FMA命令を生成しません。
たとえば、-O3 -mfma -ffp-contract=fast
のClang 3.7は、vfmadd132ss
を生成します。
私は-ffp-contract
on
にセット、off
、およびfast
でON
とOFF
に#pragma STDC FP_CONTRACT
セットのいくつかの順列を確認。すべてのケースで私は-O3 -mfma
も使用しました。
答えは簡単です。 #pragma STDC FP_CONTRACT
ONまたはOFFは違いはありません。 -ffp-contract
のみが重要です。
GCCは、それが
-ffp-contract=fast
(デフォルト)とfma
を使用しています。クランで
それは-ffp-contract=fast
とfma
- を使用しています。
-ffp-contract=on
(デフォルト)と#pragma STDC FP_CONTRACT ON
と - (デフォルトは
OFF
です)。クランと言い換える
あなたは#pragma STDC FP_CONTRACT ON
で(-ffp-contract=on
がデフォルトであるため)または-ffp-contract=fast
とfma
を得ることができます。 -ffast-math
(したがって-Ofast
)は-ffp-contract=fast
と設定されています。
MSVCとICCを調べました。 MSVCで
それは/O2 /arch:AVX2 /fp:fast
とFMA命令を使用しています。 MSVCの場合/fp:precise
がデフォルトです。
ICCではfmaと-O3 -march=core-avx2
(実際には-O1
で十分です)。これは、デフォルトでICCが-fp-model fast
を使用するためです。しかしICCは-fp-model precise
でもfmaを使用します。 ICCでfmaを無効にするには、-fp-model strict
または-no-fma
を使用します。
fmaが有効な場合、GCCとICCはfmaを使用します(GCC/Clangの場合は-mfma
、ICCの場合は-march=core-avx2
)。ただし、ClangとMSVCでは使用できません。あなたが融合した乗算・加算が許可されていることを引用した場合、「プラグマFP_CONTRACTがオフになっている場合を除き」
コンパイラのバグかもしれません。報告することを検討してください。 – fuz
gccがやっていることは大丈夫です。 FP表現を収縮することに関するFLT_EVAL_METHOD文書を読んだ後、私は 'clang' *がこれをしないと驚いています。実際の標準文書に基づいているわけではないので、私はこれを答えとして掲示するつもりではない。 –
@FUZxxl、浮動小数点タグはieee-754よりも適切だろうと思いますか? (そうなら、それを自由に変更してください)。私は浮動小数点タグも使うべきだと思う。 –