【问题标题】:Benefits of x87 over SSEx87 相对于 SSE 的优势
【发布时间】:2010-12-23 02:43:40
【问题描述】:

我知道 x87 具有更高的内部精度,这可能是人们看到的它与 SSE 操作之间的最大区别。但我不得不怀疑,使用 x87 还有其他好处吗?我有在任何项目中自动输入-mfpmath=sse 的习惯,我想知道我是否遗漏了 x87 FPU 提供的任何其他内容。

【问题讨论】:

    标签: x86 x86-64 sse fpu x87


    【解决方案1】:

    对于手写 asm,x87 有一些 SSE 指令集中不存在的指令。

    在我的脑海中,都是三角函数,例如 fsin、fcos、fatan、fatan2 和一些指数/对数。

    使用gcc -O3 -ffast-math -mfpmath=387,GCC9 实际上仍将sin(x) 内联为fsin 指令,而不管libm 中的实现将使用什么。 (https://godbolt.org/z/Euc5gp)。

    MSVC 在为 32 位 x86 编译时调用 __libm_sse2_sin_precise


    如果您的代码大部分时间都花在三角函数上,那么在使用 x87 时,您可能会看到性能略有提高或降低,具体取决于使用 SSE1/SSE2 的标准数学库实现是比慢速微码快还是慢fsin 在您使用的任何 CPU 上。

    CPU 供应商并未在最新一代 CPU 中为 x87 指令优化微码投入大量精力,因为它通常被认为已过时且很少使用。 (查看最近几代 CPU 中 Agner Fog's instruction tables 中复杂 x87 指令的 uop 计数和吞吐量:比旧 CPU 更多周期)。 CPU 越新,x87 计算 log、exp、pow 或 trig 函数的速度就越可能比许多 SSE 或 AVX 指令慢。

    即使 x87 可用,也不是所有的数学库都选择使用像 fsin 这样的复杂指令来实现像 sin() 这样的函数,或者特别是在 exp/log 中,用于操作基于日志的 FP 位模式的整数技巧很有用.

    一些 DSP 算法使用了大量的三角函数,但通常会从 SIMD 数学库的自动矢量化中受益很多。

    但是,对于您花费大部分时间进行加法、乘法等操作的数学代码。SSE 通常更快。


    还相关:Intel Underestimates Error Bounds by 1.3 quintillion - fsin 的最坏情况(fsin 输入非常接近 pi)非常糟糕。软件可以做得更好,但只能使用缓慢的扩展精度技术。

    【讨论】:

    • @LiraNuna 真的吗?我不知道任何直接从 SSE 指令集计算 sin 或 cos 的操作码。
    • 请提供来源,Quonux。
    • SSE 的速度有多快,在什么情况下它很重要?对 x87 的适当语言支持(不幸的是,它已经缺乏一段时间了)将允许直接在 0.501LSB 内计算像 d1=d2+d3+d4; 这样的表达式;如果没有这样的支持,将值计算到甚至 0.75LSB 之内需要更多的步骤。除非 SSE 比 x87 快 很多,否则我认为适当的 x87 支持比拥有更快的匹配大小算术方法更能提高性能。
    • 仅供参考,x87 FPU 的这些指令列在英特尔开发人员手册的第 5.2.4 节中,在第 121 页的 4 卷集的“先验指令”下:fsin对于正弦 fcos 对于 cosign,就像@NilsPipenbrinck 所说的那样,也有一些对数的东西
    • @Nils:如果您希望我将大部分编辑内容作为单独的答案发布,请告诉我。我添加的大部分内容在 2009 年已经是正确的,但 x87 在 2019 年更加过时了。(并且编译器对使用 sin()pow 的 SIMD 数学库实现自动矢量化的编译器支持在 2019 年要好得多,因此 DSP 优势非常值得怀疑。SIMD 通常是 DSP 的理想选择。)
    【解决方案2】:
    1. 它存在于非常旧的机器上。

    EOF

    【讨论】:

    • 但不是在真正的 真正 旧机器上 - 386 和更早的版本将 x87 协处理器作为单独的芯片,不是每个人都会购买,486 可以购买或不购买板载 487 协处理器(486DX 与 486SX)。因此,x87 在大约 1993 年(Pentium 发布,始终搭载 x87)和 2000 年(Pentium 4 与 SSE2 发布,此时您可以在 SSEx 中执行单精度和双精度浮点)之间的时间窗口内为您提供帮助.)
    • @NateEldredge 给出的问题是 x87 over SSE,因此“是否以 SSE 为目标”类型的问题,我怀疑作者在 2009 年没有考虑为 2000 年前的计算机编写软件。也许他们确实打算一直针对“复古计算机”,但不了解该计划的任何细微差别。但后来我希望我的诙谐笑话答案对大多数人有效,这个问题可以最大限度地适用于 31 年(现在 43 年)中的前 16 年(现在 28 年)。
    【解决方案3】:

    FPU 指令比 SSE 指令小,因此非常适合演示场景

    【讨论】:

    • 我不买这个;当然,严肃的演示场景程序员会压缩他们的指令流;特定领域的压缩工具应该能够像压缩 x87 指令一样压缩 SSE 指令。
    • @StephenCanon(未压缩),但如果您/他们使用任何类型的压缩,您的观点是正确的
    • @StephenCanon:1 操作数堆栈指令 (x87) 的熵比 2 操作数 SSE 指令的熵少,其中两个操作数都不是隐式的。偶尔的fxch 可能不会超过这个。我想这取决于压缩方案;我还没有看过演示实际上做了什么。不过,x87 非常适合打代码,e.g. this
    【解决方案4】:
    • 与 x87 具有相当大的传统和小型系统兼容性:SSE 是一个相对较新的处理器功能。如果您的代码要在嵌入式微控制器上运行,它很可能不支持 SSE 指令。

    • 即使没有安装 FPU 的系统通常也会提供 80x87 仿真器,这将使代码透明地运行(或多或少)。我不知道有任何 SSE 模拟器——我的一个系统肯定没有,所以最新的 Adob​​e Photoshop 元素版本拒绝运行。

    • 80x87 指令具有良好的并行操作特性,自 1982 年左右推出以来,已经对其进行了深入的探索和分析。 x86 的各种克隆可能会在 SSE 指令上停止。

    【讨论】:

    • 所以您的底线是:(a) x87 具有良好的旧版支持 (b) x87 已经得到很好的研究。
    • 我不是 100% 肯定的,但我相信在许多没有 FPU 的 32 位处理器上,浮点运算可以在 80 位值上比 64 位值更快地完成 [使用 53 位尾数和 12 位指数并不比使用 64 位尾数和 16 位指数快,但需要额外的时间来打包和解包]。我真的很困惑为什么 80 位格式在过去几十年里一直萎靡不振,因为作为 计算 格式,它似乎在各方面都优于 64 位双精度。
    • Agner Fog 的测试中没有 CPU (agner.org/optimize) 具有 SSE 但效率低下。如果存在 SSE,它总是高效的(流水线添加/子/mul),并且 SSE 划分不比 x87 划分慢。一些 CPU 将 128 位 SIMD SSE 指令分成两个 64 位半,但标量 SSE/SSE2 仍然有效。因此,您的最后一点只是过于谨慎:没有人会费心实施 slow SSE,他们只是将其完全排除在外(例如 AMD Geode 超低功耗 CPU。)
    【解决方案5】:

    floatdouble 之间的转换使用 x87(通常免费)比使用 SSE 更快。使用 x87,您可以将 floatdoublelong double 加载到寄存器堆栈或从寄存器堆栈存储,并且无需额外成本即可将其转换为扩展精度或从扩展精度转换。对于 SSE,如果类型混合,则需要额外的指令来进行类型转换,因为寄存器包含 floatdouble 值。这些转换指令相当快,但确实需要额外的时间。

    真正的解决办法是不要过度混合floatdouble,当然不要使用x87。

    【讨论】:

    • 有趣。这在现代 x64、AVX 和更高版本的 cpus 中仍然有用吗?
    猜你喜欢
    • 2017-03-19
    • 2015-07-23
    • 2011-02-26
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多