assembly - 避免 AVX-SSE (VEX) 转换惩罚

标签 assembly x86 sse avx micro-optimization

我们的 64 位应用程序有很多代码(尤其是在标准库中)在 SSE 模式下使用 xmm0-xmm7 寄存器。

我想使用 ymm 寄存器实现快速内存复制。我不能修改所有使用 xmm 寄存器的代码添加 VEX 前缀,我也认为这不切实际,因为它会增加代码的大小可能会因为需要 CPU 解码更大的指令而使其运行速度变慢.

我只想使用两个 ymm 寄存器(可能还有 zmm - 支持 zmm 的经济实惠的处理器有望在今年推出)进行快速内存复制。

问题是:如何使用 ymm 寄存器但避免转换惩罚?

当我只使用 ymm8-ymm15 寄存器(不是 ymm0-ymm7)时会发生惩罚吗? SSE 最初有 8 个 128 位寄存器 (xmm0-xmm7),但在 64 位模式下,(xmm8-xmm15) 也可用于非 VEX 前缀指令。但是,我已经查看了我们的 64 位应用程序,它只使用 xmm0-xmm7,因为它也有一个代码几乎相同的 32 位版本。只有当 CPU 实际上尝试使用以前用作 ymm 并且具有较高 128 位非零位之一的 xmm 寄存器时才会发生惩罚吗?将快速内存复制后使用的 ymm 寄存器归零不是更好吗?例如,我曾经使用 ymm 寄存器复制 32 字节的内存 - 将其归零的最快方法是什么? “vpxor ymm15, ymm15, ymm15”够快了吗? (AFAIK,vpxor 可以在 3 个 ALU 执行端口 p0/p1/p5 中的任何一个上执行,而 vxorpd 只能在 p5 上执行)。与使用它来复制 32 字节内存的 yield 相比,将它归零的时间不是更多吗?

最佳答案

另一种可能性是使用寄存器 zmm16 - zmm31。这些寄存器没有非 VEX 对应物。将 zmm16 - zmm31 与非 VEX SSE 代码混合使用没有状态转换和惩罚。这些 512 位寄存器仅在 64 位模式下可用,并且仅在具有 AVX512 的处理器上可用。

关于assembly - 避免 AVX-SSE (VEX) 转换惩罚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43879935/

相关文章:

assembly - 由 nasm 插入的冗余 DS 段覆盖前缀?

c++ - 汇编 VMOVD 的 C/C++ 内在函数

assembly - sin 和 cos 是如何在硬件上实现的?

c - Visual Studio 内联汇编程序未按预期工作

c - 有什么方法可以检查用 ObRegisterCallbacks 注册的回调是否仍然有效?

optimization - SIMD 指令降低 CPU 频率

c - 如何在 x86 实模式非操作系统程序集中打印字符串

c - SSE内存访问

assembly - SFENCE 属于什么指令集?

java - MSVC++ 只编译/禁用链接器