将有效地址加载到 x86_64 中的 XMM 寄存器的一条指令?

Posted

技术标签:

【中文标题】将有效地址加载到 x86_64 中的 XMM 寄存器的一条指令?【英文标题】:One instruction to load effective address to XMM registers in x86_64? 【发布时间】:2018-04-02 15:39:37 【问题描述】:

有什么方法可以将有效地址加载到XMM 寄存器,就像普通寄存器的LEA 一样?如果不是,最快的解决方案是什么,需要多少个周期。

【问题讨论】:

很好奇为什么要将内存位置的地址加载到 XMM 寄存器中?闻起来像是可能的 XY 问题。 xmm 寄存器是 128 位,而地址是 64 位。您是否正在寻找将 GPR 移动到 xmm 寄存器(即 (v)movq)低位的指令?我不知道有任何 lea 之类的 XMM 指令,例如 vgatherq 之类的指令,但它不会加载,只是地址生成。 FMA 在概念上相似,但它们使用 FP e 而不是整数。 我正在做一个二进制转换,我试图滥用 XMM 寄存器来更快地实现我的目标,而不是保存寄存器或使用内存计算。 根据Intel Intrinsics Guide movq 的延迟为1,倒数吞吐量为1/3。我想这不太可能导致您的程序出现瓶颈。不过,您需要提供更多背景信息才能获得更明确的答案... @chtz:英特尔表中的条目对于 Sandybridge 之后的 CPU 来说是错误的,其中 Agner Fog 对 SnB 和 Nehalem 的测试确实显示 movd/movq 是每时钟 3 个。在 IvB/HSW/SKL 上,只有 movq xmm, xmm 形式的 movq 是每个时钟 3 个,对向量寄存器的低 64 位进行零扩展。 movq xmm, r64 是 1 uop / 1 per clock,在 HSW/SKL 的端口 5 上运行。它在 AMD 上的延迟也更差,但吞吐量仍然不错(在 Bulldozer 系列上需要 2 微秒,其中 2 个整数内核共享一个 SIMD 单元)。但是,没有更好的解决方案;即使在 Bulldozer 系列上,存储/重新加载也不好;延迟也很高。 【参考方案1】:

如果我理解你的问题,也许是这样的(我知道这不是一条指令):

lea rbx, [rax+18] ; rbx = rax + 18

movq xmm, rbx ;将 rbx 移入 xmm

已经有一段时间没有看过这些了,但我记得最好的:

lea 的吞吐量为 0.5,延迟为 1

movq 的吞吐量为 0.33,延迟为 1

其中几个加起来就是每个时钟周期 2 个。

【讨论】:

是的,我可以使用另一个寄存器分两步完成。我想避免使用通用寄存器。不过还是谢谢。 您可以将值存储到内存中,然后直接从内存中加载到 XMM 寄存器中。 mov QWORD PTR [rbp-32], 8531 ;或者像 rax movq xmm0, QWORD PTR [rbp-32] 这样的寄存器 Intel 的内在函数指南有错误的 movq 吞吐量数字;在最近的 CPU 上,每个时钟只有 1 个。 ***.com/questions/49614205/…。但它不会与lea 竞争相同的执行端口。例如Haswell 仅在 port1 上运行 RIP-relative 或 3-component-LEA,但 movq xmm, r64 仅在 p5 上运行。 (简单的 LEA 可以在 p1 或 p5 上运行)。但是您不会只是,因此您需要查看周围的代码以了解端口上的瓶颈。 LEA + MOVQ 只需要 2 微秒的前端吞吐量。

以上是关于将有效地址加载到 x86_64 中的 XMM 寄存器的一条指令?的主要内容,如果未能解决你的问题,请参考以下文章

X86 操作码将 xmm 寄存器移动到通用寄存器

如何将两个打包的 64 位四字加载到 128 位 xmm 寄存器中

将 xmm 寄存器推入堆栈时出错

在 x86_64 汇编问题中添加双精度

将四字移动到 xmm

xmm 寄存器 sse x64 里面的值