我们的 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/