是的,使用vpermilps
-immediate 通常是一个错过优化的结果。vshufps
(Knight's Landing 除外),对于具有相同性能的相同操作浪费 1 个字节的代码大小。
我认为要点是vpermilps
是它可以与矢量控制操作数一起使用。在 AVX 之前,唯一的可变控制洗牌是整数pshufb
.
VPERMILPS ymm1, ymm2, ymm3/m256 https://www.felixcloutier.com/x86/vpermilps- 使用 ymm3/m256 中的控件排列 ymm2 中的单精度浮点值,并将结果存储在 ymm1 中。
但是当然,直接形式有一个完全独立的操作码,你会问为什么it存在。英特尔肯定可以只包含矢量版本,所以问题就变成了“为什么他们要包含即时版本?”它至少需要一些额外的解码硬件。洗牌单元已经具有以这种形式解压缩立即控制操作数的硬件,因为它与vshufps
,那么实施起来也许成本很低?
你唯一能立即做的事vpermilps
你不能用的vshufps
is 在一条指令中加载+随机播放, like vpermilps ymm0, [rdi], 0b00011011
反转源的每个通道中的元素。但与大多数带有立即数的指令一样,它无法微融合内存操作数,因此前端仍然是 2 个融合域微指令。 (在 AMD CPU 上,它实际上确实节省了前端带宽。)尽管如此,它仍然可以节省代码大小。vmovups ymm0, [rdi]
/ vshufps ymm0,ymm0,ymm0, 0b00011011
.
除此之外,我看不出有什么意义。它们都在两个 128 位通道中执行相同的洗牌操作,为两个通道重复使用立即数的 4x 2 位字段。 (尽管vpermilpd https://www.felixcloutier.com/x86/VPERMILPD.html and vshufpd https://www.felixcloutier.com/x86/SHUFPD.html两者都在立即数中使用 1 位字段,并且可以在每个通道中进行不同的洗牌;上面的通道使用位 2 和 3。ZMM 版本使用位 4..7 作为上面的 256。所以再一次vpermilpd dst, src, imm
与vshufpd dst, src,src, imm
,除非您使用内存源或使用随机控制向量而不是立即向量。)
这让你怀疑英特尔是否忘记了 VEX 编码将启用非破坏性vshufps
对立即洗牌做同样的事情。
或者也许他们考虑的是低功耗 CPU,例如 Knight's Landing (Xeon Phi),其中 1 源洗牌更便宜:
vpermilps
那里有 1 个周期的吞吐量,但是vshufps
or vperm2f128
具有 2 个周期的吞吐量和一个额外周期的延迟。 (根据Agner Fog 的说明书 https://agner.org/optimize/.)
所以使用vshufps
两次相同的输入会比较慢。
但在Intel的大核主流CPU上,是的,使用vpermilps
-immediate 与立即优化相比,是一个错过的优化。vshufps
,除非您可以将它与内存源一起使用。vshufps
需要两次相同的内存源,这显然是不可编码的。
AVX 的设计比 KNL 早了几年,但 ISA 设计者可能想到,未来的某些 CPU 可以通过更简单的洗牌来提高效率。
常规 Silvermont(KNL 所基于的乱序 Atom)不支持 AVX,但它具有 1 uop / 1-cycle 吞吐量和延迟shufps
。 Goldmont 的吞吐量为 0.5cshufps
.
AFAIK,英特尔还没有使用 AVX 制造低功耗核心(Xeon Phi 除外)。我认为他们不打算这样做Tremont https://en.wikichip.org/wiki/intel/microarchitectures/tremont或 Gracemont,Goldmont Plus 的继任者。