【问题标题】:What is the error of trigonometric instructions on x86?x86上三角指令的错误是什么?
【发布时间】:2014-02-20 13:15:17
【问题描述】:

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

【问题讨论】:

  • 我希望它是 IEEE 754 要求的 1 ulp。
  • @lhf: IEEE-754 对三角函数没有任何要求(如果有,要求不会是 1 ulp;IEEE-754 标准化的操作通常需要正确舍入,大致对应于 0.5 ulp 容差)。
  • 相关:randomascii.wordpress.com/2014/10/09/… - 英特尔将错误界限低估了 1.3 quintillion(在他们之前的 fsin 文档中)

标签: math x86 floating-point trigonometry x87


【解决方案1】:

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

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

只需使用更长的数据类型。使用 x86,如果您需要双精度的结果,请进行 80 位扩展双精度计算,这样您就安全了。

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

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

也就是说,让我回到你原来的问题。简短的回答:对于小操作数,它通常应该在 1 ulp 以内。对于更大的操作数,情况会变得更糟。唯一确定的方法是自己测试一下,比如this guy did。没有来自处理器供应商的可靠信息。

【讨论】:

  • 谢谢。我实际上对先验指令的错误感兴趣,但也对如何获得更高的准确性感兴趣,您也回答了。
【解决方案2】:

对于 Intel CPU,内置超越指令的准确性记录在 Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1,第 8.3.10 节超越指令准确性:

对于 Pentium 处理器和更高版本的 IA-32 处理器,超越函数的最坏情况错误在舍入到最接近(偶数)时小于 1 ulp,而在其他模式下舍入时小于 1.5 ulp。

需要注意的是,1ulp 的误差范围适用于 80 位扩展精度格式,因为所有超越函数指令都提供扩展精度结果。 Stephen Cannon 在较早的评论中指出的关于三角函数指令 FSIN、FCOS、FSCINCOS、FPTAN 的准确性损失的问题,由于使用 66 位机器 PI 减少了参数,得到了以下人员的承认英特尔。提供如下指导:

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

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

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

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

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) 单位的结果。

【讨论】:

    【解决方案3】:

    您可以阅读Intel® 64 and IA-32 Architectures Developer's Manual: Vol. 1 第 8.3.10 节关于先验指令准确性的内容。有精确的公式,也有更通俗易懂的说法

    对于 Pentium 处理器和更高版本的 IA-32 处理器,超越函数的最坏情况错误在舍入到最接近(偶数)时小于 1 ulp,而在其他模式下舍入时小于 1.5 ulp。

    【讨论】:

    • 在具体考虑三角函数时,重要要记住,它们的精度界限是根据使用 pi 的 66 位近似值的参考函数计算得出的(参见8.3.8 在同一文件中)。如果将结果与数学上精确的函数(大多数人天真地想要做的)进行比较,误差可能会比 1 ulp 大得多(一旦超出函数的基本域,误差就会非常迅速地增长)。
    • 在 Bruce Dawson 指出当范围缩小导致 +Pi 附近的 fsin 输入发生灾难性取消是多么错误之后,英特尔已经更正了该文档:Intel Underestimates Error Bounds by 1.3 quintillion
    猜你喜欢
    • 2019-06-20
    • 1970-01-01
    • 2012-10-05
    • 2013-05-20
    • 2011-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多