【问题标题】:Why both? vperm2f128 (avx) vs vperm2i128 (avx2)为什么两者都有? vperm2f128 (avx) 与 vperm2i128 (avx2)
【发布时间】:2019-05-09 03:56:31
【问题描述】:

avx 引入了指令vperm2f128(通过_mm256_permute2f128_si256 公开),而avx2 引入了vperm2i128(通过_mm256_permute2x128_si256 公开)。

它们似乎都在做完全相同的事情,它们各自的延迟和吞吐量似乎也相同。

那么为什么两条指令都存在呢?这背后一定有什么道理?有没有我忽略的东西?鉴于 avx2 对 avx 引入的数据结构进行操作,我无法想象会存在支持 avx2 但不支持 avx 的处理器。

【问题讨论】:

  • 与 SSE/AVX 中整数和浮点同时存在加载/存储和逻辑指令的原因相同:一些微架构在浮点 FPU 和整数 ALU 之间划分向量单元(可能改善芯片上的局部性,保持连线短),从而在浮点和整数之间移动数据很慢。
  • 我不完全遵循你的推理。 f 版本的签名是__m256i _mm256_permute2f128_si256 (__m256i a, __m256i b, int imm8),Intel 的描述为Shuffle 128-bits(由整数数据组成)(与permute2x128 完全相同)。鉴于它将__m256i 作为参数,它们不应该在整数ALU 中吗?或者您是说可以在 FPU 中加载 __m256i

标签: intel simd avx avx2


【解决方案1】:

内在函数与下面的实际指令之间存在一些脱节。

AVX:

所有这 3 个都生成完全相同的指令,vperm2f128

  • _mm256_permute2f128_pd()
  • _mm256_permute2f128_ps()
  • _mm256_permute2f128_si256()

唯一的区别是类型 - 在指令级别不存在。

vperm2f128 是 256 位浮点指令。在 AVX 中,没有“真正的”256 位整数 SIMD 指令。所以即使_mm256_permute2f128_si256() 是一个“整数”内在函数,它实际上只是语法糖:

_mm256_castpd_si256(
    _mm256_permute2f128_pd(
        _mm256_castsi256_pd(x),
        _mm256_castsi256_pd(y),
        imm
    )
);

从整数域到 FP 域的往返 - 从而导致绕过延迟。尽管这看起来很丑陋,但只有在 AVX 领域才能做到这一点。

vperm2f128 不是获得这种治疗的唯一指令,我发现其中至少有 3 个:

  • vperm2f128 / _mm256_permute2f128_si256()
  • vextractf128 / _mm256_extractf128_si256()
  • vinsertf128 / _mm256_insertf128_si256()

总的来说,这些内在函数的用例似乎是将数据加载为 256 位整数向量,并将它们打乱成多个 128 位整数向量以进行整数计算。同样,您存储为 256 位向量的相反。

如果没有这些“hack”内在函数,您将需要使用大量强制转换内在函数。

无论哪种方式,一个称职的编译器都会尝试优化类型。因此,即使您使用 256 位整数加载,它也会生成浮点加载/存储和洗牌。这将旁路延迟的数量减少到只有一层。 (当你从 FP-shuffle 转到 128 位整数计算时)


AVX2:

AVX2 通过为所有内容(包括随机播放)添加适当的 256 位整数 SIMD 支持来消除这种疯狂。

vperm2i128 指令是新的,同时还有一个新的内在函数 _mm256_permute2x128_si256()

这与_mm256_extracti128_si256()_mm256_inserti128_si256() 一起使您可以执行256 位整数SIMD,并且实际上完全保持在整数域中。


相同指令的整数 FP 版本之间的区别与旁路延迟有关。在较旧的处理器中,从 int FP 域移动数据存在延迟。虽然 SIMD 寄存器本身与类型无关,但硬件实现却不是。并且有额外的延迟来获得从 FP 指令到整数指令输入的数据输出。 (反之亦然)

因此,重要的是(从性能的角度来看)使用正确的指令类型来匹配正在操作的实际数据类型。

在最新的处理器(Skylake 和更高版本?)上,关于 shuffle 指令似乎不再存在 int/FP 绕过延迟。虽然指令集仍然具有这种区别,但使用不同“类型”执行相同操作的 shuffle 指令现在可能映射到同一个 uop。

【讨论】:

  • 我认为,由于 SnB 没有 vec-int/fp 绕过延迟,用于 shuffle ALU。顺便说一句,问题不是关于内在函数,而是关于为什么 AVX2 为同一个 shuffle 的整数版本引入了一个新的助记符(具有不同的操作码)。但是,是的,vec-int / FP 域显然是原因,面向未来的 CPU 机器代码在 vpaddbvmulps 指令链之间确实有 vperm2f/i128 的旁路延迟。 vpermpsvpermd 都存在的原因相同,还有其他各种对。
  • Blends do 在最近的 Intel 上具有跨域延迟。 (例如vpblenddvblendps)。 Blends 使用的晶体管比 shuffle 少得多,并且可以在每个域中复制,而不是在输入/输出上使用共享 ALU 与两个域之间进行多路复用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-14
  • 1970-01-01
  • 2021-09-21
  • 2018-03-01
  • 2018-03-30
相关资源
最近更新 更多