指令sqrtpd是否同时计算sqrt



我正在学习SIMD内部函数和并行计算。我不确定英特尔对x86指令sqrtpd的定义是否表明传递给它的两个数字的平方根将同时计算:


对源操作数(第二个操作数)中的两个、四个或八个压缩双精度浮点值的平方根执行SIMD计算,并将压缩双精度浮点数结果存储在目标操作数(第一个操作数。


我知道它明确表示SIMD计算,但这是否意味着对于该运算,将同时计算两个数字的根?

对于sqrtpd xmm,是的,现代CPU确实是并行执行的,而不是一次通过一个更窄的执行单元运行。旧的(特别是低功耗的)CPU确实做到了这一点。对于AVXvsqrtpd ymm,一些CPU确实将其分为两半执行。

但是,如果您只是将性能数字与较窄的操作进行比较,请注意,像Skylake这样的一些CPU可以将其宽div/sqrt单元的不同一半用于单独的sqrtpd/sd xmm,因此这些CPU的吞吐量是YMM的两倍,即使它可以并行执行完整的vsqrtpd ymm

与AVX-512vsqrtpd zmm相同,即使是Ice Lake也将其分为两半,正如我们从中看到的,它是3个uops(2个用于端口0,Intel将div/sqrt单元放在端口0上,它可以在其他端口上运行。)

3 uops是sqrt指令比Intel上的执行单元更宽的关键信号,但您可以查看YMM与XMM与标量XMM的吞吐量,了解它如何能够独立地为宽执行单元的不同管道提供更窄的操作。


唯一的区别是性能;目标x/y/zmm寄存器肯定具有每个输入元素的平方根。检查上的性能数字(和uop计数)https://uops.info/(目前下降,但通常非常好),和/或https://agner.org/optimize/.

允许但不能保证CPU内部有宽的执行单元,与它们支持的最宽向量一样宽,从而真正在并行管道中计算所有结果。

全宽执行单元对于除除法和平方根之外的指令是常见的,尽管从Bulldozer到Zen1之前的AMD支持只有128位执行单元的AVX/AVX2,因此vaddps ymm解码为2个uops,每一半单独执行。英特尔Alder Lake E核心的工作方式也是如此。

一些古老的和/或低功耗CPU(如Pentium-M和K8,以及Bobcat)只有64位宽的执行单元,分两半运行SSE指令(对于所有指令,而不仅仅是像div/sqrt这样的"硬"指令)。

到目前为止,只有英特尔在任何CPU上支持AVX-512,而且(除了div/sqrt)它们都有全宽执行单元。不幸的是,他们还没有想出一种方法来展示强大的新功能,比如在没有完整AVX-512的情况下,在CPU上为128和256位矢量进行掩蔽和更好的混洗。AVX-512中有一些非常好的东西与更宽的矢量完全分离。


SIMDdiv/sqrt单元通常比其他单元窄

除法和平方根本身就很慢,不可能实现低延迟。管道成本也很高;没有当前的CPU能够在每个时钟周期启动新的操作。但最近的CPU一直在这样做,至少在部分操作中是这样:我认为它们通常以牛顿-拉斐森精化的几个步骤结束,并且该部分可以流水线化,因为它只涉及乘法/加法/FMA类型的操作。

英特尔从Sandybridge开始就支持AVX,但直到Skylake才将FPdiv/sqrt单元扩展到256位。

例如,Haswell将vsqrtpd ymm作为3个uops运行,2个用于端口0(div/sqrt单元所在),1个用于任何端口,大概是为了重新组合结果。延迟大约是2倍,吞吐量是一半。(读取结果的uop需要等待两半都准备好。)

Agner Fog可能已经测试了vsqrtpd ymm读取其自身结果的延迟;IDK如果英特尔可以让一半的操作在另一半准备好之前开始,或者合并的uop(或者不管是什么)最终会迫使它在启动另一半div或sqrt之前等待两半都准备好。div/sqrt以外的指令具有全宽执行单元,并且总是需要等待两半。

我还在一个关于浮点除法与浮点乘法的表中收集了各种CPU上YMM和XMM的divps/pd/sd/ss吞吐量和延迟

要完成@PeterOrderes的伟大答案,这确实是架构的依赖。。然而,人们可以期望在最新的主流处理器上并行计算两个平方根(或者可能在ALU级别高效地流水线计算)。以下是英特尔体系结构的延迟和吞吐量(您可以从英特尔获得):

单吞吐量><10>Broadwell哈斯韦尔常春藤大桥
体系结构 单延迟封装的XMM吞吐量封装的XMM
Skylake 18 18 6
骑士登陆 40 3833

是的,压缩操作数上的SIMD(矢量)指令对所有矢量元素执行相同的操作"并行";。这是由于sqrtsd(一个double上的标量平方根)和sqrtpd(128位寄存器中两个double上的压缩平方根)具有相同的延迟。

256位及更大矢量的vsqrtpd在一些处理器上可能具有更高的延迟,因为操作是在矢量的128位部分上顺序执行的。vdivpd可能也是如此,但其他指令则不然——大多数情况下,无论向量大小如何,延迟都是相同的。如果你想确定,请查阅说明表。