AArch64中32位寄存器的性能优势?

问题描述 投票:0回答:1

在AArch64/ARM64中进行整数运算时,使用32位W{n}寄存器与64位X{n}寄存器是否有性能差异?

例如,

add W1, W2, W3
add X1, X2, X3
快吗?
sdiv W1, W2, W3
sdiv X1, X2, X3
快吗?根据实现的不同,它会有所不同吗(例如 Apple M1/M2/M3 与 64 位 Qualcomm Snapdragon)?

我的直觉是使用 W{n} 时有一个较小的性能优势,但我不确定除了在紧密循环中之外它是否真的很重要。我对讨论此问题的官方 ARM 文档(如果有)感兴趣。在我目前正在编写的汇编代码中,我主要使用 X{n} 来保持一致性,但我想知道当我知道/期望数据适合 32 位时是否值得切换到 W{n}。

assembly cpu-architecture apple-m1 arm64 cpu-registers
1个回答
0
投票

@PeterCordes 提供的链接和 @NateEldredge 的评论让我陷入了一些有趣的兔子洞。

tl;dr: 对于

ADD
SUB
LSL
等算术,使用 W{n} 与 X{n} 时没有性能差异。然而,在做
udiv
/
sdiv
时,有轻微的W{n}优势。根据实现(Cortex 与 M1)的不同,
ldp
stp
的调用方式可能会产生微小的差异。

来源:


皮质-A77

我怀疑这可能适用于大多数 AArch64 实现。

  • 使用 W{n} 相对于 X{n} 的优势:
    • udiv
      sdiv
      :W 形式的执行延迟为 5 到 12,X 形式的执行延迟为 5 到 20。
    • 乘法累加(
      madd
      msub
      )没有区别,因此“纯”乘法没有区别。
  • 使用 W{n} 而不是 X{n} 时的惩罚:
    • ldp
      ldnp
      带符号立即偏移量:W 形式的吞吐量为 2,但 X 形式的吞吐量仅为 1。
    • stp
      stnp
      带符号立即偏移量:W 形式的吞吐量为 2,但 X 形式的吞吐量仅为 1。
    • 有趣的是,使用带有前索引或后索引的加载/存储对没有区别。所以
      ldp W0, W1, [SP, #-16]
      (没有感叹号)有惩罚,但
      ldp W0, W1, [SP, #-16]!
      ldp W0, W1, [SP], #16
      没有!

苹果M1

Apple 的 AArch64 实现与 Cortex 版本显着不同。这是我能找到的:

  • 使用加载/存储对,与 Cortex 相比,情况相反!
      使用 W 形或 X 形时,
    • ldnp
      stnp
      没有区别。
    • 对于前索引和后索引,
    • ldp
      stp
      在 W 形式中稍微更快,但对于带符号偏移量情况,它们的速度相同。
    • 在 W 形式中,
    • ldr
      str
      也稍微更快。差异似乎比
      ldp
      /
      stp
      更小。
  • 使用 W{n} 的优点:
    • udiv
      sdiv
      :W 形式的执行延迟为 7 到 8,X 形式的执行延迟为 7 到 9。
  • 使用 W{n} 时的惩罚:
    • mov W0, W1
      必须执行,而
      mov X0, X1
      只是内部寄存器重命名。
    • mov
      使用 W{n} 寄存器,从/到 SP 的速度稍慢。

结论

据我所知,人们唯一关心 W 形式与 X 形式的时间是在皮质上进行大量

udiv
/
sdiv
时。在 M1 上,差异很小。总的来说,当差异确实存在时,差异很小,我怀疑在现实生活中的代码中根本没有多大关系。

我想到的另一种情况可能很重要,那就是实现一个带有展开的

memcpy
/
ldp
stp
:在 Cortex 上,执行有符号偏移并且仅进行一次索引前或索引后调用可能会稍微有点更快,而在 M1 上,最好对所有
ldp
/
stp
使用索引前或索引后调用。

© www.soinside.com 2019 - 2024. All rights reserved.