x86/x64 是否使用 SIMD 寄存器进行高精度浮点运算或专用 FP 寄存器?
我的意思是高精度版本,而不是常规double
精度。
x86/x64 是否使用 SIMD 寄存器进行高精度浮点运算或专用 FP 寄存器?
我的意思是高精度版本,而不是常规double
精度。
正如@EricPostpischil 指出的那样,FPU 堆栈仍然可用并公开了一个 80 位精度的算术(不确定处理器是否仍然具有完整的逻辑,或者这部分是否在硬件级别进行了仿真)。它以long double
类型提供给 GCC 中的开发人员。例如,为方法生成的程序集
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 位浮点值的寄存器(采用 Intel 格式,即 IEEE 754 格式,略有变化)。
各种 SIMD 单元(SSE、AVX 等)具有更大的寄存器,可用于许多事情,但只有将它们用作 32 位和 64 位浮点的指令。