gpt4 book ai didi

assembly - X86:如何将xmm0的下半部分设置为0,而不影响上半部分?

转载 作者:行者123 更新时间:2023-12-01 09:12:09 27 4
gpt4 key购买 nike

我使用 xmm0 有 128 位的系统。
我想将 [63...0] 设置为零,而不影响 [127...64]。
我用:

MOV RAX, 0xFFFFFFFFFFFFFFFF
MOVQ xmm2, RAX
PSHUFD xmm2, xmm2, 0b00001111
PAND xmm1, xmm2

有没有更快的方法?

最佳答案

您可以通过以下方式更有效地创建常量

pcmpeqd xmm2,xmm2       ; xmm2 = all-ones.  Needs any ALU port
pslldq xmm2, 8 ; left shift by 8 bytes. Needs the shuffle port

PAND xmm1, xmm2

(另见 Agner Fog's optimization guide ;他有一节关于动态创建常量。还有 What are the best instruction sequences to generate vector constants on the fly? )

或者正如@RossRidge 所建议的那样,如果您需要足够频繁地在缓存中保持热状态,则使用常量的内存源操作数可能是最有效的,但不能只是将其从循环中取出并将其保存在寄存器中。

或者混入一个新的低 8 字节零 .
pxor   xmm2, xmm2       ; xmm2=0; very efficient on Intel CPUs; no back-end uop

movsd xmm1, xmm2 ; runs on port5 only on Intel CPUs, like shuffles.

(作为从内存加载, movsd 零扩展。但对于 reg-reg 移动它和 movss 保留目标上部未修改。)

混合的替代方法更有效,但需要的不仅仅是 SSE2:
  • SSE4.1:pblendw xmm1, xmm2, 0b00001111 - 更糟糕的一切(或同等速度但更糟糕的代码大小)。仍然只在 Intel 的 port5 上运行。锐龙运行 movsd xmm,xmm在比 pblendw 还要多的端口上.与 pblendw 相比,低功耗 Atom/Silvermont 在更多端口上运行 movsd,但 Goldmont 和 KNL 对此和 movsd 的吞吐量为 2/clock。所以它永远不会比 movsd 好。
  • SSE4.1 blendpd xmm1, xmm2, 0b01 (或 blendps ) - 与 vpblendd 一样有效,但如果在整数指令之间使用会导致绕过转发延迟。如果您在吞吐量方面遇到瓶颈,这可能没问题,尤其是在您必须避免后端压力的情况下。
  • AVX2:vpblendd xmm1, xmm1, xmm2, 0b0011 - 在任何 AVX2 CPU 的任何 ALU 端口上运行。

  • 某些 CPU 可能还具有 movsd 的旁路延迟在整数指令之间,但 Sandybridge-family 对洗牌非常宽容。

    movsd 一样有效在某些 CPU 上,只需要 SSE1:
  • movhlps xmm1, xmm2 - 用 xmm2 的高 qword(也为零)替换 xmm1 的低 qword。在 Ryzen 或 Silvermont 上效率较低。

  • 同样, shufpdshufps可以复制 xmm1的上半部分进入归零寄存器的上半部分。 (如果您不想破坏原始 reg,则很有用)。但是你可以用 movsd 做到这一点更轻松、更高效。

    也可能: movlps xmm, [mem]加载零,可能是您刚刚存储到堆栈中。它不允许寄存器源操作数,并且需要在 Intel 上使用 port5 uop(shuffle/uncommon blend)。它可以微融合成一个融合域 uop,但它大多比 pand 差使用内存源,因为它可以在更少的端口上运行。

    关于assembly - X86:如何将xmm0的下半部分设置为0,而不影响上半部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59480753/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com