質問

リリースモードとデバッグモードでコンパイルすると、アプリケーションで異なる浮動小数点値が生成されます。私が見つけた唯一の理由は、バイナリトレースログを保存し、リリースビルドのログがデバッグビルドからわずかに離れているため、32ビット浮動小数点値の下位2ビットが約1/2異なるようですケースの。

この「違い」を考慮してくださいバグであるか、この種の違いが予想されます。これはコンパイラのバグか内部ライブラリのバグでしょうか。

例:

LEFTPOS and SPACING are defined floating point values.
float def_x;
int xpos;

def_x = LEFTPOS + (xpos * (SPACING / 2));

問題はX360コンパイラに関するものです。

役に立ちましたか?

解決

リリースモードには、異なるFP戦略が設定されている場合があります。最適化のレベルに応じて、さまざまな浮動小数点演算モードがあります。たとえば、MSVCには、厳密、高速、正確なモードがあります。

他のヒント

PCでは、浮動小数点レジスタは80ビット幅であることを知っています。したがって、計算が完全にFPU内で行われる場合、80ビットの精度という利点が得られます。一方、中間結果が通常のレジスタに移動されて戻されると、32ビットに切り捨てられ、異なる結果が得られます。

リリースビルドでは、FPUレジスタに中間結果を保持する最適化がありますが、デバッグビルドでは、おそらく中間結果をメモリとレジスタ間で単純に前後にコピーすることを考慮してください。 >

これがX360でも起こるかどうかわかりません。

同僚とリリースの違い、コンパイラの違いが原因のデバッグビルドの違いを見つけるのに協力しました。

/ fp(浮動小数点を指定する動作)

これはバグではありません。浮動小数点のアップレーションには一定の不正確さがあります。リリースモードでは、最適化によって操作の順序が変更され、わずかに異なる結果が得られます。ただし、違いは小さいはずです。大きい場合は、他の問題が発生している可能性があります。

他の人が指摘したさまざまな浮動小数点モードに加えて、SSEまたは類似のベクトル最適化がリリース用にオンになっている場合があります。浮動小数点演算を標準レジスタからベクトルレジスタに変換すると、結果の下位ビットに影響を与える可能性があります。一般に、ベクトルレジスタは標準の浮動小数点レジスタよりも狭い(ビットが少ない)ためです。

バグではありません。このタイプの違いは予想されるものです。

たとえば、一部のプラットフォームにはメモリに格納されているよりも多くのビットを使用するフロートレジスタがあるため、レジスタに値を保持すると、メモリに格納してメモリから再ロードする場合と比べてわずかに異なる結果が得られます。

この不一致は、コンパイラの最適化が原因で発生する可能性があります。これは通常、リリースモードで実行されますが、デバッグモードでは実行されません。たとえば、コンパイラは、実行を高速化するために一部の操作の順序を変更する場合があります。これにより、浮動小数点の結果にわずかな違いが生じる可能性があります。

つまり、バグではない可能性が高いと思います。これが本当に心配な場合は、デバッグモードで最適化を有効にしてみてください。

前述のように、浮動小数点レジスタは浮動小数点よりも精度が高いため、最終結果の精度はレジスタの割り当てに依存します。

一貫性のある結果が必要な場合は、変数を揮発性にすることができます。これにより、結果が遅くなり、精度が低下しますが、一貫性のある結果になります。

コンパイラが浮動小数点演算を並べ替えることができるコンパイラスイッチを設定した場合、たとえば/ fp:fast-それは明らかにバグではありません。

このようなスイッチを設定しなかった場合、それはバグです。CおよびC ++標準では、コンパイラが許可なく操作を並べ替えることはできません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top