将有效地址加载到 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 寄存器的一条指令?的主要内容,如果未能解决你的问题,请参考以下文章