x86/x64 は、高精度浮動小数点演算または専用 FP レジスタに SIMD レジスタを使用しますか?
通常のdouble
精度ではなく、高精度バージョンを意味します。
x86/x64 は、高精度浮動小数点演算または専用 FP レジスタに SIMD レジスタを使用しますか?
通常のdouble
精度ではなく、高精度バージョンを意味します。
@EricPostpischil が指摘するように、FPU スタックは引き続き利用可能であり、80 ビット精度の演算を公開します (ただし、プロセッサにまだ完全なロジックがあるかどうか、またはこの部分がハードウェア レベルでエミュレートされているかどうかは不明です)。これは、GCC の開発者がlong double
型を使用して利用できるようになります。たとえば、メソッドの生成されたアセンブリ
long double f(long double a, long double b)
{
return a*b ;
}
なる
fldt 16(%rbp)
fldt 32(%rbp)
fmulp %st, %st(1)
このアーカイブ電子メールは、そのようなデータを使用するための便利な要素を提供します。
long double my_logl(long double x) { long double y; __asm__ volatile( "fldln2\n" "fldl %1\n" "fyl2x" : "=t" (y) : "m" (x)); return y; }
SSE、AVX、またはその他のベクトル拡張を使用せずにコードをコンパイルすると、コードは 80 ビット FPU を使用してそのような命令を生成し、異なる値を出力する可能性があります。説明するコード例を次に示します。
double epstest(long double a, long double b)
{
long double y ;
y = a + b ;
y = y - a ;
return y ;
}
#include <cstdio>
int main()
{
double x = 1.0 ;
double y = 1e-17 ;
double z = x + y ;
z = z - x ;
printf ("double: %lf + %le - %lf = %le\n", x, y, x, z);
double res = epstest (x, y) ;
printf ("long double: %lf + %le - %lf = %le\n", x, y, x, res);
return 0 ;
}
そして出力:
double: 1.000000 + 1.000000e-17 - 1.000000 = 0.000000e+00
long double: 1.000000 + 1.000000e-17 - 1.000000 = 9.974660e-18
long double
x86_64 のソフトウェアでは、より高い精度 ( を超える) が実装されています。
FPU (浮動小数点ユニット) には、80 ビットの浮動小数点値用のレジスタがあります (IEEE 754 形式にわずかな変更を加えた Intel 形式)。
さまざまな SIMD ユニット (SSE、AVX など) には、さまざまな用途に使用できるより大きなレジスタがありますが、それらを 32 ビットおよび 64 ビットの浮動小数点として使用するための命令しかありません。