VPERMILPS指令(_mm_permute_ps)有什么意义?

时间:2019-01-13 12:12:12

标签: assembly x86 avx instruction-set

AVX指令集引入了VPERMILPS,它似乎是SHUFPS的简化版本(对于两个输入寄存器相同的情况)。

例如,以下说明:

c5 f0 c6 c1 00          vshufps xmm0,xmm1,xmm1,0x0

可以替换为:

c4 e3 79 04 c1 00       vpermilps xmm0,xmm1,0x0

如您所见,VPERMILPS版本多花了一个字节,并且执行相同的操作。根据指令表,两条指令占用1个CPU周期,并且具有相同的吞吐量。

引入这种说明有什么意义?我想念什么吗?

编辑: 这两条指令之间有一个区别。 VPERMILPS将上限通道设置为零,而SHUFPS则将其保持不变。

1 个答案:

答案 0 :(得分:6)

vpermilps(对于Knight's Landing除外)相比,立即使用vshufps-速成通常是错过优化的情况,因为相同操作和相同性能会浪费1个字节的代码大小。


我认为vpermilps的要点是它可以与向量控制操作数一起使用。在AVX之前,唯一的可变控制随机播放是整数pshufb

  

VPERMILPS ymm1, ymm2, ymm3/m256-使用ymm3 / m256中的控件在ymm2中置换单精度浮点值,并将结果存储在ymm1中。


但是,当然,立即数形式具有完全独立的操作码,您在问为什么存在。英特尔肯定可以只包含矢量版本,因此问题变为“为什么它们包含立即版本?” 。它至少需要一点额外的解码硬件。随机播放单元已经具有以这种形式解包立即控制操作数的硬件,因为它与vshufps相同,因此实现起来便宜吗?

您无法使用即时vpermilps执行的唯一操作vshufps在一条指令中加载+随机播放,例如vpermilps ymm0, [rdi], 0b00011011进行反转源中每个通道中的元素。但是,像大多数带有立即数的指令一样,它无法对存储器操作数进行微融合,因此前端仍为2个融合域。 (在AMD CPU上,它确实确实节省了前端带宽。)不过,与vmovups ymm0, [rdi] / vshufps ymm0,ymm0,ymm0, 0b00011011相比,它节省了代码大小。

除此之外,我没有多大意义。它们在两个128位通道中都执行相同的混洗,为两个通道重用立即数的4x 2位字段。 (虽然vpermilpdvshufpd在其立即数中都使用1位字段,并且可以在每个通道中执行不同的混洗;较高通道使用位2和3。ZMM版本使用位4。 7为高位256。因此,vpermilpd dst, src, immvshufpd dst, src,src, imm相同,除非您使用内存源或使用改组控制向量而不是立即数。)

这让您想知道英特尔是否忘记了VEX编码将使无损vshufps能够立即执行随机操作。


或者也许他们想起了低功耗CPU,例如Knight's Landing(至强披披),在这种情况下,一站式洗牌更便宜:

vpermilps的吞吐量为1周期,但是vshufpsvperm2f128的吞吐量为2周期,并有额外的延迟周期。 (根据Agner Fog's instruction tables。)

因此,将vshufps与相同的输入一起使用两次会比较慢。

但是在Intel大核心主流CPU上,可以使用vpermilps-immediate与vshufps相比是错过优化的方法,除非您可以将其与内存源一起使用。 vshufps将需要两次相同的内存源,这显然是无法编码的。

AVX的设计比KNL提前了好几年,但也许ISA设计师铭记在心,将来某些CPU可能会通过更简单的改组来提高效率。

常规Silvermont(KNL所基于的无序Atom)不支持AVX,但它具有1 uop / 1个周期的吞吐量和shufps的延迟。 Goldmont对于shufps的吞吐量为0.5c。

AFAIK,英特尔仍未使用AVX制造低功耗内核(至强融核除外)。我不认为他们打算与Tremont或Gracemont(Goldmont Plus的继任者)一起使用。