【发布时间】:2010-12-23 02:43:40
【问题描述】:
我知道 x87 具有更高的内部精度,这可能是人们看到的它与 SSE 操作之间的最大区别。但我不得不怀疑,使用 x87 还有其他好处吗?我有在任何项目中自动输入-mfpmath=sse 的习惯,我想知道我是否遗漏了 x87 FPU 提供的任何其他内容。
【问题讨论】:
我知道 x87 具有更高的内部精度,这可能是人们看到的它与 SSE 操作之间的最大区别。但我不得不怀疑,使用 x87 还有其他好处吗?我有在任何项目中自动输入-mfpmath=sse 的习惯,我想知道我是否遗漏了 x87 FPU 提供的任何其他内容。
【问题讨论】:
对于手写 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)非常糟糕。软件可以做得更好,但只能使用缓慢的扩展精度技术。
【讨论】:
d1=d2+d3+d4; 这样的表达式;如果没有这样的支持,将值计算到甚至 0.75LSB 之内需要更多的步骤。除非 SSE 比 x87 快 很多,否则我认为适当的 x87 支持比拥有更快的匹配大小算术方法更能提高性能。
fsin对于正弦 fcos 对于 cosign,就像@NilsPipenbrinck 所说的那样,也有一些对数的东西
sin() 和 pow 的 SIMD 数学库实现自动矢量化的编译器支持在 2019 年要好得多,因此 DSP 优势非常值得怀疑。SIMD 通常是 DSP 的理想选择。)
EOF
【讨论】:
FPU 指令比 SSE 指令小,因此非常适合演示场景
【讨论】:
fxch 可能不会超过这个。我想这取决于压缩方案;我还没有看过演示实际上做了什么。不过,x87 非常适合打代码,e.g. this
与 x87 具有相当大的传统和小型系统兼容性:SSE 是一个相对较新的处理器功能。如果您的代码要在嵌入式微控制器上运行,它很可能不支持 SSE 指令。
即使没有安装 FPU 的系统通常也会提供 80x87 仿真器,这将使代码透明地运行(或多或少)。我不知道有任何 SSE 模拟器——我的一个系统肯定没有,所以最新的 Adobe Photoshop 元素版本拒绝运行。
80x87 指令具有良好的并行操作特性,自 1982 年左右推出以来,已经对其进行了深入的探索和分析。 x86 的各种克隆可能会在 SSE 指令上停止。
【讨论】:
float 和 double 之间的转换使用 x87(通常免费)比使用 SSE 更快。使用 x87,您可以将 float、double 或 long double 加载到寄存器堆栈或从寄存器堆栈存储,并且无需额外成本即可将其转换为扩展精度或从扩展精度转换。对于 SSE,如果类型混合,则需要额外的指令来进行类型转换,因为寄存器包含 float 或 double 值。这些转换指令相当快,但确实需要额外的时间。
真正的解决办法是不要过度混合float 和double,当然不要使用x87。
【讨论】: