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

2024-02-17

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-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, immvshufpd 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 的继任者。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

VPERMILPS 指令 (_mm_permute_ps) 有什么意义? 的相关文章

  • 在 x86-64 CPU 上通过交叉修改代码重现意外行为

    Question 对于可能在 x86 或 x86 x64 系统上触发意外行为的交叉修改代码有哪些想法 在这些系统中 交叉修改代码中的所有操作均已正确完成 但在执行处理器之前执行序列化指令除外修改代码 如下所述 我有一个 Core 2 Duo
  • 使用 AVX 内在函数代替 SSE 并不能提高速度 - 为什么?

    我已经使用 Intel 的 SSE 内在函数相当长一段时间了 并取得了良好的性能提升 因此 我希望 AVX 内在函数能够进一步加速我的程序 不幸的是 直到现在情况并非如此 可能我犯了一个愚蠢的错误 所以如果有人能帮助我 我将非常感激 我使用
  • Nasm 打印到下一行

    我用 nasm Assembly 编写了以下程序 section text global start start Input variables mov edx inLen mov ecx inMsg mov ebx 1 mov eax 4
  • 从 NASM 调用 C 函数 _printf 会导致分段错误

    我一直在尝试使用 NASM 在 Mac OS 和 Windows 上学习 64 位汇编 我的代码是 extern printf section data msg db Hello World 10 0 section text global
  • 为什么我的空循环在 Intel Skylake CPU 上作为函数调用时运行速度是原来的两倍?

    我正在运行一些测试来比较 C 和 Java 并遇到了一些有趣的事情 在 main 调用的函数中 而不是在 main 本身中 运行具有优化级别 1 O1 的完全相同的基准代码 导致性能大约翻倍 我正在打印 test t 的大小 以毫无疑问地验
  • AVX-512CD(冲突检测)与原子变量访问有何不同?

    所以我在看他们展示了如何 void Histogram const float age int const hist const int n const float group width const int m const float o
  • 使用 (float&)int 进行类型双关可以正常工作,(float const&)int 会像 (float)int 一样转换吗?

    VS2019 发布 x86 template
  • “mov (%ebx,%eax,4),%eax”如何工作? [复制]

    这个问题在这里已经有答案了 一直在从事装配作业 并且在很大程度上我对装配非常了解 或者至少对于这项任务来说足够好 但这个 mov 的声明让我很困惑 如果有人能解释这个 mov 语句如何操作寄存器值 我将非常感激 mov ebx eax 4
  • 使用 MIPS 从 Big Endian 到 Little Endian 无需逻辑运算?

    我正在使用 MIPS QtSpim 将 32 位字从 Big Endian 转换为 Little Endian 我下面显示的内容已检查且正确 不过我想知道还有什么其他方法可以让我进行转换 我虽然只使用了旋转和移位 但如果没有逻辑运算 我就无
  • 阴影空间示例

    EDIT 我接受了下面的答案 并添加了我自己的代码的最终修订版 希望它向人们展示影子空间分配的实际示例 而不是更多的文字 编辑 2 我还设法在 YouTube 视频 所有内容 的注释中找到了一个调用约定 PDF 的链接 其中有一些关于 Li
  • AVX-512 指令编码 - {er} 含义

    在 Intel x86 指令集参考中 有许多 AVX 512 指令在指令中具有可选的 er 例如 VADDPD 的一种形式定义为 EVEX NDS 512 66 0F W1 58 r VADDPD zmm1 k1 z zmm2 zmm3 m
  • X86 预取优化:“计算 goto”线程代码

    我有一个相当重要的问题 我的计算图有循环和多个 计算路径 我没有制作一个调度程序循环 其中每个顶点将被一一调用 而是将所有预先分配的 框架对象 放置在堆中 代码 数据 这有点类似于线程代码 甚至更好 CPS 只是在堆中跳转 执行代码 每个代
  • 如何编译GCC生成的asm?

    我正在玩一些汇编代码 有些事情困扰着我 我编译这个 include
  • 如何仅使用单个数组在 JavaScript 中模拟调用堆栈

    我正在看维基百科页面 https en wikipedia org wiki Call stack在调用堆栈上 并尝试理解这个图像 据我所知 哈哈 const memory memory 0 3 top of stack pointer m
  • 是否可以在VM内使用VMX CPU指令?

    VM guest 内部的进程是否有可能使用 VMX AMD V VT x CPU 指令 然后由外部 VMM 处理而不是直接在 CPU 上处理 Edit 假设外部VM使用VMX本身来管理其虚拟客户机 即它在Ring 1中运行 如果可能的话 是
  • Visual Studio 2012 本机 C++ DLL x86 编译

    我最近将我的工具集从 Win 7 x86 Visual Studio 2010 升级到 Win 8 x64 Visual Studio 2012 但是 现在我的本机 C dll 编译为 x64 而不是 x86 除了将代码移至新操作系统并将其
  • 在 x86 汇编中将 64 位常量移至内存

    我正在使用 Intel x64 程序集 NASM 编译器 尝试将 0x4000000000000000 常量移至内存 该常量在 ieee 754 标准双精度中应等于 2 0 我正在使用的代码是 define two 0x4000000000
  • 高效memcspn

    有谁知道 memcspn 函数的有效实现吗 它的行为应该类似于 strcspn 但在内存缓冲区中查找跨度 而不是在以 null 结尾的字符串中查找跨度 目标编译器是 VisualC 谢谢 卢卡 一种近乎最佳的实现 size t memcsp
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • 从类模板参数为 asm 生成唯一的字符串文字

    我有一个非常特殊的情况 我需要为类模板中声明的变量生成唯一的汇编程序名称 我需要该名称对于类模板的每个实例都是唯一的 并且我需要将其传递给asm关键字 see here https gcc gnu org onlinedocs gcc 12

随机推荐