Delphi には、32 ビット アプリケーションと 64 ビット アプリケーションの両方としてコンパイルされた同じ数のクランチ ソース コードがあります。ログ ファイルから、数値がわずかに (1e-14 相対誤差) 異なることがわかります。そのため、32 ビット コードと 64 ビット コードを実行しているときに、同じ CPU が浮動小数点演算を異なる方法で実行する可能性があるかどうか疑問に思っています。それとも、コンパイラが責任を負うものですか。
2 に答える
コードが明示的に を使用していないと仮定しますExtended
。そのデータ型は 32 ビットと 64 ビットで異なるため (32 ビットでは 10 バイト、64 ビットでは 8 バイト)、 を明示的に使用するとExtended
すぐに違いが生じます。Double
すべての変数にを使用していると仮定します。以下の引数は に等しく転送されますがSingle
。
さらに、これの最も一般的な理由は、2 つの浮動小数点ユニットの動作の違いです。
32 ビット コードで使用される x87 ユニットは、中間値を 80 ビット拡張精度に格納します。64 ビット コードで使用される SSE ユニットは、中間値を 64 ビット倍精度に格納します。
これで、コントロール ワードを使用して x87 ユニットを構成し、中間値を 64 ビット精度で格納できるようになりました。パフォーマンスの点では違いはありませんが、32 ビットと 64 ビットの結果がより近くなるように調整されます。
それでも、異なるユニットでまったく同じ結果が得られるわけではありません。実際、すべての x87 ユニットでまったく同じ結果が得られるわけではありません。これらの単位はすべて IEEE754 に準拠していますが、その規格は計算にある程度の余裕を与えます。
さらに、三角法、対数、べき乗などの高次の計算は、32 ビットと 64 ビットの間でまったく異なる方法で実行されます。32 ビット ユニットには、64 ビット ユニットよりも多くの機能が組み込まれています。たとえば、三角関数はすべて 64 ビットの RTL で実装されていることが、Delphi ソース コードでわかります。32 ビット コードでは、x87 ops を呼び出すことによって実装されます。
肝心なのは、浮動小数点計算が関係している場合、32 ビット プログラムと 64 ビット プログラムが正確に一致することは決してないということです。多少の誤差は許容する必要があります。