我在fpu之前几年读到过,当切换到单精度模式时,除法和sqr的速度是正常模式的两倍。
(查看源码http://stereopsis.com/FPU.html)
它仍然是这样的吗?这样的切换可以加快一些循环的速度,使内部产生大量的浮点代码?
与第二个问题相关,例如,当进行系统(winapi)调用时,我可以在代码中自由地玩弄FPU精度吗,与fpu取整模式和系统端一样,api是否也会破坏我对它的设置?
发布于 2019-03-07 15:53:49
是的,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精度位控制HW分频器的方式与divss或divsd完全相同。
下面的详细信息
是的,x87可以限制为64位或32位总宽度(double或float),低于标准的80位。在最坏的情况下,fsqrt fdiv 和fdiv的速度与相同精度的标量SSE/SSE2的速度大致相同(sqrtss =标量fsqrt/ sqrtsd =标量双精度)。没有比它运行得更快或更慢的了。
It does not make x87比SSE更快,所以在这一点上,它主要是一个CPU历史的奇闻。
显然DirectX是这样做的(习惯于?)实际上将x87精度设置为24位尾数(float),并使用MSVC的CRT启动将其设置为53位尾数(double)。参见Bruce Dawson的https://randomascii.wordpress.com/2012/03/21/intermediate-floating-point-precision/。但微软的历史怪癖是个例外;其他工具链/ OSes不会与x87打交道。
Agner Fog's instruction tables没有提到针对Sandybridge或更新版本的CPU的x87 precision。这可能意味着它不再有帮助,或者(我认为) Agner认为它不值得一提。他的SnB和较新的表没有任何脚注,所以我认为这就是解释。据我所知,瑞士央行的分隔器与NHM没有太大不同。
对于Nehalem:
fdiv 7-27个周期延迟=吞吐量(根本不是流水线),脚注上写着: values.divsd/divpd divisors or low precision 22 values.divsd/divpd 7-22 cycles latency=throughput.divss/divps 7-14 cycles latency=throughput.因此,最佳情况下的性能(除法器占用7个周期)对于所有形式都是相同的,最坏的情况会变得更差,尾数位越多。
我们知道除法器HW是迭代的,并且必须持续更长的时间来计算更多的位,所以将x87精度设置为24位或53位可以100%地帮助中的性能,就像使用 precision 一样。无论如何,它们共享相同的硬件执行单元。
IvyBridge最终完成了FP分割器的流水线。哈斯韦尔没有对IvB的div编号做任何重大更改。以下是HSW编号:
fdiv 10-24c延迟,8-18c throughputdivsd / divpd xmm:10-20c延迟,8-14c throughputdivss /divpd xmm:10-13c延迟,7c吞吐量(固定延迟适用于计划程序)另请参阅Floating point division vs floating point multiplication,在那里我收集了最近英特尔CPU的Agner Fog数据,包括256位的YMM向量。我在这里省略了x87,因为它基本上与高性能无关。
通常情况下,你会使用SSE1,因为它通常更快的(由于平面寄存器集和2操作数指令而不是堆栈,在fxch和fld寄存器拷贝上没有花费前端带宽)。在某些情况下使用SIMD的机会(通常是4x浮点sqrt的结果与1相同),与将x87微处理器设置为32位相比,这是一个巨大的优势。
大多数SSE数学指令的吞吐量和延迟与其对应的x87指令相似,但x87的开销更大。
如果你需要在没有SSE1的情况下生成与古老的CPU兼容的32位二进制文件,是的,如果fdiv和fsqrt性能对你的代码很重要,你可以将CPU精度降低到24位。(可能还会加速一些微码x87指令,如fsin和fyl2x,IDK。)
或者,如果将精度降低到float太过分了,那么您将在SSE2中查看double的数学规则。它是x86-64的基准,所以只有在出于某种原因必须生成32位二进制文件的情况下才值得考虑。最新的没有它的CPU是Athlon XP。(如果你不算像current Geode这样的东西。)
与四舍五入模式和系统端相同,是否也会破坏我的设置?
AFAIK,任何事情都不会改变舍入模式。这将是一个很大的差异,并且对性能没有帮助。
如果有人能够证明这样做是合理的,那么有人会为了C的性能而这样做,这些C使用不带SSE转换和截断指令的(int)float (或者对于x87版本是SSE3 fisttp ),以避免必须将x87舍入模式设置为截断(接近0),然后在每次将fp值转换为整数时恢复它。
大多数编译器在优化时都假设是四舍五入的。
发布于 2012-10-04 00:41:43
我的理解是,在传统的x86浮点处理器上,精度对速度的影响几乎在i486中就结束了。不过,在8087年前,这是一个常见的优化。
https://stackoverflow.com/questions/12707961
复制相似问题