我相信整数加法或减法总是同时无论操作数有多大。 所需的ALU的输出被稳定可以通过输入操作数而变化,但是CPU元件时,它利用ALU输出将等待足够长的时间,以使任何整数操作将在SAME周期被处理。 (所需的周期为ADD,SUB,MUL和DIV会有所不同,但ADD将采取同样的循环,无论输入操作数,我想的)。
这是真正的浮点运算,太?
我试图实施方案,其中包括大量的浮点运算。 我不知道这是有帮助的规模我处理的快速运行时间的数字。
我相信整数加法或减法总是同时无论操作数有多大。 所需的ALU的输出被稳定可以通过输入操作数而变化,但是CPU元件时,它利用ALU输出将等待足够长的时间,以使任何整数操作将在SAME周期被处理。 (所需的周期为ADD,SUB,MUL和DIV会有所不同,但ADD将采取同样的循环,无论输入操作数,我想的)。
这是真正的浮点运算,太?
我试图实施方案,其中包括大量的浮点运算。 我不知道这是有帮助的规模我处理的快速运行时间的数字。
TL:DR:避免非正规号码和你的罚款 。 如果你不需要渐进下溢,将非正规数为零,冲洗要在x86 MXCSR零位,或者类似的其他架构。 在大多数的CPU,产生非规格化结果陷阱微码,所以它需要数百个循环而不是5的。
见昂纳雾的insn的表用于x86 CPU的细节,也是x86的标签维基。
这取决于你的CPU上,而是典型的现代的FPU都在这方面类似。
除了非正规操作数, 延迟/吞吐量加/减/ MUL操作是不依赖于数据的典型的现代的FPU(包括x86,ARM和其他)。 他们通常是完全流水,但多周期的延迟(即新MUL可以开始执行每一个周期,如果其输入是准备好),这使得乱序调度可变延迟不方便。
可变等待时间将意味着两个输出将在同一个周期就绪,击败的完全流水线它的目的,并使其无法调度可靠地避免冲突等它具有已知但混合延迟指令/微指令处理时一般不会。 ( 这些讲义关于阶管线展示如何这对回写(WB)构造风险 ,但同样的想法适用于ALU本身需要一个额外的缓冲,直到可以用手关闭所有的结果已经就绪。)
作为对频谱的高性能端的示例: 英特尔Haswell的 :
mulpd
(标量,双精度128B或256B向量):5c中的延迟,每两个1C吞吐量(两个单独的ALU)。 addpd
/ subpd
:3C延迟,每1C吞吐量之一。 (但是,该加载单元是相同的端口上与MUL / FMA单元之一) divpd
(标量或128B-载体):10〜20℃的等待时间,每8-14c吞吐量之一。 (另外,相同的端口MUL / FMA单元之一上)。 对于较慢256B向量(在div ALU不是全宽度)。 稍快的float
S,不像加/减/ MUL。 sqrtpd
:16C延迟,每8-14c吞吐量之一。 同样不实际的宽度,更快float
。 rsqrtps
(快非常近似的,仅适用于float
):5C延迟,每1℃吞吐量之一。 DIV / SQRT是例外:他们的吞吐量和延迟是数据依赖 。
有用于股利或开方没有快速并行算法, 即使是在硬件 。 某种迭代计算的需要,因此完全流水线将需要复制大量非常相似的硬件中,每个流水线阶段。 不过,现代的英特尔x86 CPU的有部分流水线股利和开方,以互惠吞吐量不到延迟。
相比于MUL,DIV / SQRT具有更低的吞吐量(〜1/10或更差),并显著较高的延迟(〜2倍至4倍)。 在现代的FPU的DIV /开方单元的未完全流水线性质意味着它可以是可变等待时间而不在ALU输出端口造成太多的冲突。
SSE / AVX没有实现正弦/余弦/ EXP /日志为单一的指令; 数学库应自己的代码。
许多优秀的数学库没有使用的x87 fsin
SSE存在两种甚至之前; 它的微码上的所有现有的实现,因此内部实现使用相同的80位加/减/ MUL / DIV /开方的硬件,您可以用简单的指令的程序; 有没有专门的fsin
硬件(或至少没有太多;也许查找表)。 同样对于大多数其他TRIG /超然的x87类似功能fyl2x
。
这将是很好,如果有一些专门的fsin
硬件,因为范围内还原到+/-π/ 2可以真正从更高的精度受益输入π/ 2的非常接近的倍数。 fsin
使用相同的80位丕恒(64位尾数),您从中获取fldpi
。 这是最接近的可表示long double
到Pi的准确值,有缘接下来的两个二进制数字是零,所以它实际上是精确到66位。 但它仍然导致的1.37千万亿单位在最后的地方最坏情况的最大误差,留下少于四位正确 。 ( 布鲁斯·道森的一系列有关浮点的文章是优秀的 ,你一定要读他们,如果你要写一些浮点代码。 指数在这一个。 )
英特尔不能改善的x87的范围还原精度fsin
不中断与现有的CPU数值的兼容性。 这绝对有助于不同的x86处理器上运行以相同的输入相同的指令时,给数值相同的结果。 在软件中,你可以做的范围,减少自己与扩展精度浮点,像所谓的两双获得四精度(但仍然只的指数范围内double
)。 双人大床可以用SSE2填充双重指示相当有效地实施。 一个SSE2库实现的fsin
可能去时速超过精度和作出同样的折衷为的x87硬件; 仅使用常规的double
减少范围丕恒,导致在最坏的情况下,较大的误差。 这将是对于一些使用情况的有效的选择,这是软件的一个很大的优势:你可以选择你的用例合适的软件实现。
IDK有关的x87 EXP或登录指令,像fyl2x
。 他们是微编码的,所以他们没有什么特别的速度,但可能是确定的准确性。 尽管如此,现代数学库不会从XMM寄存器复制值X87只是该指令。 该指令的x87可能比你可以用正常的SSE运算指令做慢。 (而且几乎可以肯定不是更快。)
欲了解更多有关快速互惠和快速倒数平方根,请参阅为什么SSE标量的sqrt(x)的比rsqrt(X)* X慢?
RSQRTPS用牛顿-拉夫逊迭代略比正常sqrtps不太准确。 在英特尔的Haswell / SKYLAKE微架构,这是大致相同的延迟IIRC,但可能有更好的吞吐量。 如果没有NR迭代,这对于大多数应用太不精确。
无论如何,这已经得到了相当的x86特定的。 穆尔主场迎战开方的相对性能在很大程度上取决于CPU微架构,但即使隔着86主场迎战ARM与硬件的FPU其他大多数现代的CPU,你会发现, mul
和add
的性能是不依赖于数据。