为什么将 32 位寄存器移动到堆栈然后从堆栈移动到 xmm 寄存器?
Why move 32-bit register to stack then from stack to xmm register?
我正在 64 位机器上使用 gcc -m32
进行编译。
以下有什么区别?请注意,这是 AT&T 语法。
# this
movd %edx, %xmm0
# and this
movl %edx, (%esp)
movd (%esp), %xmm0
机器状态的唯一区别是第二个版本在堆栈上留下一个副本1。
GCC 的默认调整由于某种原因在内存中反弹。 (最近的 GCC 可能已经在某些情况下修复了这个问题)。尽管 AMD 的优化手册确实推荐了它,但在大多数 CPU 上,包括 AMD 在内,大多数情况下它通常更差。请参阅 GCC 错误 80820 and 80833 回复:GCC 的整数 <-> xmm 一般策略。
使用 movd
将花费 1 个 ALU 微指令,而不是存储和加载微指令,因此前端的微指令较少,但 不同 微指令后端,因此根据周围的代码,store/reload 策略可以减少特定执行端口的压力。
在所有 CPU 上,ALU movd
的延迟均优于 store/reload,因此 store/reload 的唯一优势是可能的吞吐量。
Agner Fog says 在他的 Bulldozer 微架构 pdf 中(CPU 最慢 movd %edx, %xmm0
):
The transport delays between the integer unit and the floating
point/vector unit are much longer in my measurements than specified in
AMD's Software Optimization Guide. Nevertheless, I cannot confirm that
it is faster to move data from a general purpose register to a vector
register through a memory intermediate, as recommended in that guide.
脚注 1:如果您真的想要那样,单独的商店通常仍然是实现该状态的更好选择。相同的 uops 数量和更低的延迟(尤其是在 Intel CPUs 上。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
我正在 64 位机器上使用 gcc -m32
进行编译。
以下有什么区别?请注意,这是 AT&T 语法。
# this
movd %edx, %xmm0
# and this
movl %edx, (%esp)
movd (%esp), %xmm0
机器状态的唯一区别是第二个版本在堆栈上留下一个副本1。
GCC 的默认调整由于某种原因在内存中反弹。 (最近的 GCC 可能已经在某些情况下修复了这个问题)。尽管 AMD 的优化手册确实推荐了它,但在大多数 CPU 上,包括 AMD 在内,大多数情况下它通常更差。请参阅 GCC 错误 80820 and 80833 回复:GCC 的整数 <-> xmm 一般策略。
使用 movd
将花费 1 个 ALU 微指令,而不是存储和加载微指令,因此前端的微指令较少,但 不同 微指令后端,因此根据周围的代码,store/reload 策略可以减少特定执行端口的压力。
在所有 CPU 上,ALU movd
的延迟均优于 store/reload,因此 store/reload 的唯一优势是可能的吞吐量。
Agner Fog says 在他的 Bulldozer 微架构 pdf 中(CPU 最慢 movd %edx, %xmm0
):
The transport delays between the integer unit and the floating point/vector unit are much longer in my measurements than specified in AMD's Software Optimization Guide. Nevertheless, I cannot confirm that it is faster to move data from a general purpose register to a vector register through a memory intermediate, as recommended in that guide.
脚注 1:如果您真的想要那样,单独的商店通常仍然是实现该状态的更好选择。相同的 uops 数量和更低的延迟(尤其是在 Intel CPUs 上。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