为啥将 32 位寄存器移动到堆栈然后从堆栈移动到 xmm 寄存器?
Posted
技术标签:
【中文标题】为啥将 32 位寄存器移动到堆栈然后从堆栈移动到 xmm 寄存器?【英文标题】:Why move 32-bit register to stack then from stack to xmm register?为什么将 32 位寄存器移动到堆栈然后从堆栈移动到 xmm 寄存器? 【发布时间】:2015-04-17 14:20:53 【问题描述】:我在 64 位机器上使用 gcc -m32
进行编译。
以下有什么区别?请注意,这是 AT&T 语法。
# this
movd %edx, %xmm0
# and this
movl %edx, (%esp)
movd (%esp), %xmm0
【问题讨论】:
第一个不应该是movd %edx, %xmm0
吗?
您忘记启用优化?不同之处在于第二个在堆栈上留下了一个副本,以后可能需要。不过,更好的方法是将堆栈写入添加到版本 #1。
@PascalCuoq 你是对的。让我编辑问题。
@lurker 哦,对不起。我假设使用 gcc 编译会默认提供 AT&T 语法。我应该明确表示。
那是我的错。你所拥有的显然是 AT&T 语法,但我习惯于思考英特尔,我完全过滤掉了线索。我收回我的评论... :)
【参考方案1】:
机器状态的唯一区别是第二个版本在堆栈上留下一个副本1。
出于某种原因,GCC 的默认调整会在内存中反弹。 (最近的 GCC 可能已在某些情况下修复了此问题)。尽管 AMD 的优化手册确实推荐了它,但在大多数情况下,包括 AMD 在内的大多数 CPU 通常都会更糟。请参阅 GCC 错误 80820 和 80833 re: GCC 的整数 xmm 策略。
使用 movd
将花费 1 ALU uop,而存储和加载 uop,因此前端的 uop 较少,但后端的 uop 不同不同,因此取决于围绕代码存储/重新加载策略可以减少特定执行端口的压力。
ALU movd
的延迟优于所有 CPU 上的存储/重新加载,因此存储/重新加载的唯一优势是可能的吞吐量。
Agner Fog says 在他的 Bulldozer 微架构 pdf 中(最慢的 CPU movd %edx, %xmm0
):
整数单元和浮点单元之间的传输延迟 在我的测量中,点/矢量单位比指定的长得多 AMD 的软件优化指南。尽管如此,我无法确认 将数据从通用寄存器移动到向量更快 按照该指南中的建议,通过内存中间体进行注册。
脚注 1:如果您真的想要这样,单独的商店通常仍然是实现该状态的更好选择。相同的 uops 数和更低的延迟(尤其是在 Intel CPU 上。AMD Bulldozer / Steamroller 对于movd (x)mm, r32/r64
有 10 / 5 个周期的延迟。在 Intel 上为 1 个周期。)
movd %edx, %xmm0 # ALU int -> xmm transfer
movl %edx, (%esp) # and store a copy if you want it
【讨论】:
以上是关于为啥将 32 位寄存器移动到堆栈然后从堆栈移动到 xmm 寄存器?的主要内容,如果未能解决你的问题,请参考以下文章