我已经读到,在较老的fpu上,将fpu转换为单精度模式之前的几年,除法和sqr的速度是正常模式下的两倍。
(检查其来源http://stereopsis.com/FPU.html)
仍然是这样,并且像这样进行切换可以加快某些循环的速度,并在其中包含许多浮动代码?
第二个问题有关,例如,在进行系统(winapi)调用时,我可以在代码中自由地以FPU精度玩弄吗,与fpu取整模式和系统端相同,api是否还会破坏我的设置?
最佳答案
是的,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精度位大概与divss
或divsd
一样控制硬件分频器。
详情如下
是的,x87的总宽度可以限制为64位或32位(double
或float
),低于标准的80位。是的,这确实会稍微加快fsqrt
和fdiv
最坏情况的速度,使其速度与具有相同精度的标量SSE / SSE2大致相同(sqrtss
=标量单/ sqrtsd
=标量双)。没有其他东西运行得更快或更慢。
它不能使x87的速度比SSE快,因此在这一点上主要是对CPU历史的好奇。
显然DirectX确实(过去使用过?)实际上将x87精度设置为24位尾数(float
),而MSVC的CRT启动通常将其设置为53位尾数(double
)。参见布鲁斯·道森的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:fdiv
7-27个周期的延迟=吞吐量(根本没有流水线),并在脚注中指出“舍入因子或精度低会产生低值”。divsd
/ divpd
7-22周期潜伏期=吞吐量。divss
/ divps
7-14个周期潜伏期=吞吐量。
因此,对于所有形式,最佳情况下的性能(占用7个周期的除法器)都是相同的,最坏的情况是,越多的尾数位可能越差。
我们知道,分频器硬件是迭代的,并且必须花更长的时间才能计算更多的位,因此将x87精度设置为24或53位与使用divss
完全一样,可以提高100%的合理性。他们仍然共享相同的硬件执行单元。
IvyBridge最终实现了FP分压器的流水线设计。与IvB相比,Haswell并未对div编号进行任何重大更改。这些是HSW编号:fdiv
10-24c延迟,8-18c吞吐量divsd
/ divpd xmm
:10-20c延迟,8-14c吞吐量divss
/ divps xmm
:10-13c延迟,7c吞吐量(固定延迟对于调度程序来说很好)
另请参见Floating point division vs floating point multiplication,其中我收集了针对最近的Intel CPU的Agner Fog数据,包括256位YMM向量。我在这里省略了x87,因为它与高性能无关。
通常,您只需要使用SSE1,因为它通常更快(由于使用了平面寄存器集和2操作数指令而不是堆栈,因此无需在fxch
和fld
寄存器副本上花费前端带宽)。而且在某些情况下使用SIMD的机会(通常将4倍的float sqrt与1并发),与将x87 FPU设置为32位相比,这是一个巨大的胜利。
大多数SSE数学指令的吞吐量和等待时间与x87类似,但x87的开销更大。
如果您需要使32位二进制文件与甚至没有SSE1的古代CPU兼容,可以的话,如果fdiv
和fsqrt
性能对代码很重要,则可以将x87精度降低到24位。 (可能还会加快一些微编码的x87指令,例如fsin
和fyl2x
,IDK。)
或者,如果将精度降低到float
太过猛烈,那么您正在寻找XMM regs中的double
数学的SSE2。它是x86-64的基准,因此再次值得考虑的是,如果由于某种原因必须制作32位二进制文件。没有它的最新CPU是Athlon XP。 (如果您不算像当前的Geode之类的东西。)
与fpu舍入模式和系统端相同,api还会破坏我的设置吗?
AFAIK,舍入模式不变。那将是一个很大的差异,并且对性能没有帮助。
如果有人能够证明这样做的合理性,那么有人会为使用(int)float
而不使用SSE截断转换指令(对于x87版本为SSE3 fisttp
)使用C的性能而这样做。将x87舍入模式截断(向0),然后在每次将FP值转换为整数时都将其还原。
大多数编译器在优化时都假定取整。
关于performance - 将fpu切换为单精度,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12707961/