x86上三角指令的错误是什么?

时间:2014-02-20 13:15:18

标签: math x86

在哪里可以找到有关x86处理器上三角函数指令的错误范围的信息?

3 个答案:

答案 0 :(得分:5)

你问的问题很少是一个有趣的问题,很可能你真的想知道一些不同的东西。所以让我先回答不同的问题:

如何计算一定精度的三角函数?

只需使用更长的数据类型。对于x86,如果您需要具有双精度的结果,请执行80位扩展双精度计算,并确保安全。

如何获得与平台无关的准确度?

您需要专门的软件解决方案,例如MPFR

那就是说,让我回到你原来的问题。简短回答:对于小操作数,它通常应在1 ulp以内。对于较大的操作数,情况越来越糟。唯一能找到答案的方法是自己测试,例如this guy did。处理器供应商没有可靠的信息。

答案 1 :(得分:2)

您可以阅读关于先验指导准确性的Intel® 64 and IA-32 Architectures Developer's Manual: Vol. 1部分8.3.10。有一个精确的公式,但也有更容易理解的陈述

  

使用奔腾处理器和后来的IA-32处理器时,超越函数的最坏情况误差在舍入到最接近(偶数)时小于1 ulp,在其他模式下舍入时小于1.5 ulps。

答案 2 :(得分:2)

对于英特尔CPU,内置先验指令的准确性记录在Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1,第8.3.10节“超越指令准确度”中

  

使用奔腾处理器和后来的IA-32处理器时,超越函数的最坏情况误差在舍入到最接近(偶数)时小于1 ulp,在其他模式下舍入时小于1.5 ulps。

应该注意的是,1 ulp的误差界限适用于80位扩展精度格式,因为所有超越函数指令都提供了扩展精度结果。 Stephen Cannon在之前关于三角函数指令FSIN,FCOS,FSCINCOS,FPTAN的数学参考相对于数学参考的精度损失的评论中指出的问题,由于66位机器PI的参数减少,得到了承认英特尔。指导如下:

  

无论目标精度(单次,双次或双次扩展)如何,将参数减少到绝对值小于FSIN约3π/ 4的值是安全的,对于FCOS小于约3π/ 8是安全的。 ,FSINCOS和FPTAN。 [...]例如,精度测量表明,FSIN的双扩展精度结果不会出现大于0.72 ulp的误差| x | < 2.82 [...]   同样,对于| x |,FCOS的双扩展精度结果不会有大于0.82 ulp的误差< 1.31 [...]

进一步认识到,当y = 1时,对数函数指令FYL2X和FYL2XP1的1 ulp的误差界限才成立(这在英特尔的一些旧文档中并不清楚):

  

指令FYL2X和FYL2XP1是两个操作数指令,只有当y等于1时才能保证在1 ulp以内。当y不等于1时,最大ulp误差始终在1.35

使用多精度库,可以直接将英特尔的声明用于测试。为了收集以下数据,我使用了Richard Brent的MP库作为参考,并在指定的时间间隔内运行了2个 31 随机测试用例:

Intel Xeon CPU E3-1270 v2 "IvyBridge", Intel64 Family 6 Model 58 Stepping 9, GenuineIntel

2xm1 [-1,1]        max. ulp = 0.898306 at x = -1.8920e-001 (BFFC C1BED062 C071D472)
sin [-2.82,+2.82]  max. ulp = 0.706783 at x =  5.1323e-001 (3FFE 8362D6B1 FC93DFA0)
cos [-1.41,+1.41]  max. ulp = 0.821634 at x = -1.3201e+000 (BFFF A8F8486E 591A59D7)
tan [-1.41,+1.41]  max. ulp = 0.990388 at x =  1.3179e+000 (3FFF A8B0CAB9 0039C790)
atan [-1,1]        max. ulp = 0.747328 at x =  1.2252e-002 (3FF8 C8BB9E06 B9EB4DF8), y =  3.9204e-001 (3FFD C8B8DC94 AA6655B4)
y2lx [0.5,2.0]     max. ulp = 0.994396 at x =  1.0218e+000 (3FFF 82C95B56 8A70EB2D), y =  1.0000e+000 (3FFF 80000000 00000000)
yl2x [1.0,1.2]     max. ulp = 1.202769 at x =  1.0915e+000 (3FFF 8BB70F1B C5F7E103), y = -9.8934e-001 (BFFE FD453A23 AC926478)
yl2xp1 [-0.7,1.44] max. ulp = 0.990469 at x =  2.1709e-002 (3FF9 B1D61A98 BF349080), y =  1.0000e+000 (3FFF 80000000 00000000)
yl2xp1 [-1, 1]     max. ulp = 1.206979 at x =  9.1169e-002 (3FFB BAB69127 C1D5C158), y = -9.9281e-001 (BFFE FE28A91F 132F0C35)

虽然此类非详尽测试无法证明错误界限,但发现的最大错误似乎证实了英特尔的文档。

我没有任何现代的AMD处理器可供测试,但确实有旧的32位Athlon CPU的测试数据。完全披露:我为32位Athlon处理器中使用的超越函数指令设计了算法。对于所有说明,我的准确度目标小于1 ulp;然而,对于上面已经提到的三角函数的66位机器PI减少参数的相同警告也适用。

Athlon XP-2100 "Palomino", x86 Family 6 Model 6 Stepping 2, AuthenticAMD

2xm1 [-1,1]        max. ulp = 0.720006 at x =  5.6271e-001 (3FFE 900D9E90 A533535D)
sin [-2.82, +2.82] max. ulp = 0.663069 at x = -2.8200e+000 (C000 B47A7BB2 305631FE)
cos [-1.41, +1.41] max. ulp = 0.671089 at x = -1.3189e+000 (BFFF A8D0CF9E DC0BCA43)
tan [-1.41, +1.41] max. ulp = 0.783821 at x = -1.3225e+000 (BFFF A947067E E3F4C39C)
atan [-1,1]        max. ulp = 0.665893 at x =  5.5333e-001 (3FFE 8DA6B606 C58B206A) y =  5.5169e-001 (3FFE 8D3B9DC8 5EA87546)
yl2x [0.4,2.5]     max. ulp = 0.716276 at x =  6.9826e-001 (3FFE B2C128C3 0EF1EC00) y = -1.2062e-001 (BFFB F7064049 BC362838)
yl2xp1 [-1,4]      max. ulp = 0.691403 at x =  1.9090e-001 (3FFC C37C0397 F8184934) y = -2.4796e-001 (BFFC FDE93CA9 980BF78C)

AMD64 Architecture Programmer’s Manual, Vol. 1,在第6.4.5.1节“超越结果的准确性”一节中,将错误界限记录如下:

  

x87计算以双扩展精度格式执行,因此超越函数为每个浮点数据类型的最后位置(ulp)提供精确到一个单位内的结果。