【问题标题】:What's the point of the VPERMILPS instruction (_mm_permute_ps)?VPERMILPS 指令 (_mm_permute_ps) 的意义何在?
【发布时间】:2019-06-07 16:28:30
【问题描述】:

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 有三个“正交”选项:1. 压缩单压缩与压缩双压缩,2. 立即混洗控制整数与可变控制向量,以及 3. 128 位 xmm 与 256 位 ymm。选择不同的组合,这会产生 8 个不同版本的vpermilps。巧合的是,其中一个与vshufps 具有相同的行为。因此,如果vpermilps xmm0,xmm1,0x0 不存在,那将是不合逻辑的。尽管如此,人们可能更喜欢vshufps xmm0,xmm1,xmm1,0x0,它确实节省了一个字节。 (我不确定这条评论是否适合作为答案。)
  • 问题仍然存在,但是,为什么存在带有立即控制整数的vpermilps,因为还有vshufpd。
  • 回复:您的编辑:只有 shufps 的 SSE 编码不会修改上层通道,是的,这不适用于 vpermilps。但是您的示例是vshufps,它的上车道为零,并且可以复制和随机播放。我想这在不会导致 AVX/SSE 转换停滞(Haswell/Broadwell 除外)的 CPU 上可能很有用,例如用于插入 YMM 的 SSE pinsrd/q。如果您避免使用 xmm8..15 中的 REX 前缀,我想它还可以节省更多的代码字节来使用 SSE1 shufps。只是一个 2 字节的操作码 + modrm + imm8 = 总共 4 个字节,而 2 字节的 VEX + 操作码是 5 个。

标签: assembly x86 avx instruction-set


【解决方案1】:

是的,使用 vpermilps-immediate 与 vshufps(骑士登陆除外)相比,通常是一个错过的优化,在相同的性能下浪费了 1 个字节的代码大小。


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

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


当然,直接形式有一个完全独立的操作码,你在问为什么 它 存在。英特尔绝对可以只包含矢量版本,所以问题变成了“为什么他们包含即时版本?”这至少需要一些额外的解码硬件。 shuffle 单元已经有硬件以这种形式解压缩直接控制操作数,因为它与vshufps 相同,所以实现起来可能很便宜?

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

除此之外,我认为没什么意义。它们都在两个 128 位通道中执行相同的洗牌,为两个通道重用立即数的 4x 2 位字段。 (虽然vpermilpd 和vshufpd 都在其立即数中使用 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-source shuffle 更便宜:

vpermilps 那里有 1 个周期的吞吐量,但 vshufps 或 vperm2f128 有 2 个周期的吞吐量和一个额外的延迟周期。 (根据Agner Fog's instruction tables。)

因此,使用 vshufps 两次输入相同的输入会更慢。

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

AVX 的设计比 KNL 早了好几年,但也许 ISA 设计者考虑到,未来的某些 CPU 可能会通过更简单的 shuffle 来提高效率。

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

据我所知,英特尔仍然没有使用 AVX 制造低功耗内核(Xeon Phi 除外)。我认为他们不打算与 Goldmont Plus 的继任者 Tremont 或 Gracemont 合作。

【讨论】:

    猜你喜欢
    • 2020-09-18
    • 2016-08-05
    • 2011-02-05
    • 2010-10-25
    • 2020-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多