将fpu切换为单精度

时间:2012-10-03 11:55:09

标签: performance assembly optimization x86 x87

我已经读过,在fpu之前的几年,当切换到单精度模式时,分区和sqr的速度是普通模式的两倍。

(检查来源http://stereopsis.com/FPU.html

是不是仍然如此,这样的切换可以加快一些循环,在里面制作大量的浮动代码?

第二个问题相关,我可以在进行系统(winapi)调用时在我的代码中自由地玩FPU精度,与fpu舍入模式和系统端相同,api是否也会破坏我的设置?< / p>

2 个答案:

答案 0 :(得分:2)

是的,Agner Fog的吞吐量/等待时间数字与降低x87精度以加速最坏情况完全一致。

考虑到现代div / sqrt硬件的工作方式,使用Radix-16或Radix-1024分频器可以迭代地计算结果的更多位,这也很有意义,因此需要更少的正确位意味着您可以更快地停止。 (How sqrt() of GCC works after compiled? Which method of root is used? Newton-Raphson?The integer division algorithm of Intel's x86 processors

考虑到x87 fdiv和SSE1 divss在相同的硬件上运行,并且divss具有相同的最佳情况(约数除数),但最坏的情况也更好,这也是有道理的。 x87个精度位大概可以像divssdivsd一样控制硬件分频器。

详细信息


是的,x87可以限制为64位或32位宽度(doublefloat),低于标准的80位。 是的,这确实可以稍微加快fsqrtfdiv最坏情况的速度,使其达到与具有相同精度的标量SSE / SSE2相同的速度({{1}标量单/ sqrtss =标量双)。没有其他东西运行得更快或更慢。

它的确使x87的速度比SSE快,因此这主要是CPU历史上的好奇。

很显然,DirectX确实(用于?)实际上将x87精度设置为24位尾数(sqrtsd),而MSVC的CRT启动程序通常将其设置为53位尾数(float)。参见布鲁斯·道森(Bruce Dawson)的https://randomascii.wordpress.com/2012/03/21/intermediate-floating-point-precision/。但是微软的历史怪异是例外。其他工具链/操作系统不会与x87混为一谈。

Agner Fog's instruction tables并未提及Sandybridge或更高版本的CPU的x87精度。这可能意味着它不再有用,或者(我认为)Agner认为这不值得一提。他的SnB和更新的表格没有任何脚注,所以我认为这就是解释。据我所知,SnB的分频器与NHM并没有太大区别。

对于Nehalem:

  • double 7-27个周期的延迟=吞吐量(完全没有流水线),并在脚注中指出圆除数或低精度给出较低的值。 / em>

  • fdiv / divsd 7-22个周期latency = throughput。

  • divpd / divss 7-14个周期latency = throughput。

因此,所有形式的最佳情况下的性能(占用7个周期的除法器)都是相同的,最坏的情况是,可能会增加尾数位。

我们知道分频器HW是迭代的,必须继续花费更长的时间才能计算更多的比特,因此将x87精度设置为24或53位有助于准确地实现 是100%合理的与使用divps的方式相同。他们仍然共享相同的硬件执行单元。

IvyBridge最终流水线化了FP分隔器。与IvB相比,Haswell没有对div编号进行任何重大更改。这些是HSW编号:

  • divss延迟10-24c,吞吐量8-18c
  • fdiv / divsd:10-20c延迟,8-14c吞吐量
  • divpd xmm / divss:10-13c延迟,7c吞吐量(固定延迟对于调度程序来说很好)

另请参阅Floating point division vs floating point multiplication,在这里我收集了最近的Intel CPU的Agner Fog数据,包括256位YMM向量。我把x87遗漏了,因为它与高性能无关。


通常只使用SSE1,因为它通常速度更快(由于平坦的寄存器组和2个寄存器,因此divps xmmfxch寄存器副本上没有前端带宽花费-operand指令,而不是堆栈)。而且在某些情况下使用SIMD的机会(通常将4倍的float sqrt与1并发),与将x87 FPU设置为32位相比,这是一个巨大的胜利。

大多数SSE数学指令的吞吐量和等待时间与x87类似,但x87的开销更大。

如果您需要制作与甚至没有SSE1的古代 CPU兼容的32位二进制文​​件,是的,您可以将x87精度降低到24位,如果{{ 1}}和fld的性能对于您的代码很重要。 (可能还会加快IDK fdivfsqrt等一些微编码的x87指令的速度。)

或者如果将精度降低到fsin太过激烈,那么您正在针对XMM规则中的fyl2x数学学习SSE2。它是x86-64的基准,因此再次值得考虑的是,如果由于某种原因必须制作32位二进制文​​件。没有它的最新CPU是Athlon XP。 (如果您不算像当前的Geode之类的东西。)


  

与fpu舍入模式和系统端相同,api是否还会破坏我的设置?

AFAIK,舍入模式不变。那将是一个很大的差异,并且对性能没有帮助。

如果有人能够证明这样做是对的,那么有人会为使用float而无需使用SSE截断转换指令(或对于x87版本为SSE3 double)的C执行此操作),以避免必须将x87舍入模式设置为截断(向0),然后在每次将FP值转换为整数时都将其还原。

大多数编译器在优化时都假定取整。

答案 1 :(得分:-1)

我的理解是,传统x86 FPU的精度对速度的影响几乎以i486结束。尽管如此,这是8087天的常见优化。