13

x87 FPUは、内部80ビット精度モードを使用していることで注目に値します。これにより、コンパイラーやマシン間で予期しない再現不可能な結果が生じることがよくあります。.NETで再現可能な浮動小数点演算を検索したところ、.NETの両方の主要な実装(MicrosoftとMono)が64ビットモードでx87ではなくSSE命令を出力することがわかりました。

SSE(2)は、32ビットフロートには厳密に32ビットレジスタを使用し、64ビットフロートには厳密に64ビットレジスタを使用します。適切な制御ワードを設定することにより、オプションで非正規化数をゼロにフラッシュできます。

したがって、SSEはx87の精度関連の問題に悩まされておらず、唯一の変数は制御可能な非正規化動作であるように見えます。

超越関数(x87とは異なりSSEによってネイティブに提供されない)の問題は別として、SSEを使用すると、マシンとコンパイラ間で再現可能な結果が保証されますか?たとえば、コンパイラの最適化は異なる結果につながる可能性がありますか?私はいくつかの矛盾する意見を見つけました:

SSE2をお持ちの場合は、それを使用して、その後も幸せに暮らしてください。SSE2は32bと64bの両方の操作をサポートし、中間結果はオペランドのサイズになります。--Yossi Kreininhttp://www.yosefk.com/blog/consistency-how-to-defeat-the-purpose-of-ieee-floating-point.html

..。

SSE2命令(...)はIEEE754-1985に完全に準拠しており、他のプラットフォームとの再現性(静的な丸め精度のおかげで)と移植性が向上します。Muller et aliis浮動小数点演算ハンドブック-p.107

でも:

また、浮動小数点にSSEまたはSSE2を使用することはできません。これは、指定が少なすぎて決定論的ではないためです。-John Watte http://www.gamedev.net/topic/499435-floating-point-determinism/#entry4259411

4

2 に答える 2

15

SSEは完全に指定されています*。Mullerは浮動小数点演算の専門家です。誰を信頼しますか、彼またはgamedevフォーラムの誰か?

(*)rsqrtssのようなIEEE-754以外の操作には、実際にはいくつかの例外があります。Intelは動作を完全に指定していませんが、IEEE-754の基本的な操作には影響せず、さらに重要なことに、動作を実際に変更することはできません。この時点では、多くの点でバイナリ互換性が損なわれるため、指定されたとおりに機能します。

于 2013-03-01T06:08:31.723 に答える
6

Stephenが指摘したように、SSEアセンブリコードの特定の部分によって生成された結果は再現可能です。同じコードに同じ入力をフィードすると、最後に同じ出力が得られます。(つまり、John Watteの引用は完全に間違っています。)

You threw the word "compilers" in there, though. That's a different ball game entirely. Many compilers are still quite bad at preserving the correctness of floating-point code. (The ATLAS errata page makes mention that clang "fails to produce correct code for some operations.") If you use special functions in your code, you're also, to some extent, at the mercy of whoever implemented your math library.

于 2013-03-01T15:43:41.990 に答える