【问题标题】:What is fastest way to copy a variable into another?将变量复制到另一个变量的最快方法是什么?
【发布时间】:2013-11-08 19:56:58
【问题描述】:

假设我有 2 个变量。

x = 1  
y = 2  

最终结果应该是:

x = 2  
y = 1  

我想到了以下方法:

temp = x // clone x
x = y
y = temp

或(异或交换)

x = x XOR y
y = x XOR y
x = y XOR x

我想得到有关低级内存等的答案...
最快的方法是什么?

注意:
我想得到一个奖励答案,假设没有副作用(代码,cpu),这是最快的,还是有其他更快的?

【问题讨论】:

  • 这取决于很多事情,我怀疑是否有明确的答案。
  • 任何没有测量的答案都是错误的。答案还取决于周围的代码和架构。
  • 最快的交换方式是不交换。相反,将寄存器分配交换给变量。例如,如果xr0 中,而yr1 中,则“在”您说xr1 中和yr0 中的交换之后。这并不总是一种选择,但当它出现时,它是无与伦比的,因为它实际上需要零时间,实际上什么都没有发生,这只是解释。
  • 这听起来像是他试图优化的 XY 问题。

标签: performance memory copy cpu-registers


【解决方案1】:

问题是现代 CPU 架构不会让您得到这个答案。它们会隐藏许多效果,并会暴露出许多非常微妙的效果。

如果你有 CPU 寄存器中的值并且你有一个备用寄存器,那么temp 方式要么是最快的方式,要么是功耗最低的方式。

使用 XOR 或 +/-(顺便说一句非常简洁!)方法适用于您无法承受额外位置(额外内存变量或额外寄存器)的情况。这可能看起来很奇怪,但在 C 预处理器宏中,例如不能(轻松)声明新变量。

当变量在内存中时,所有变体很可能在任何高性能 CPU 上表现相同。即使编译器不优化代码,CPU 也会避免几乎所有的内存访问,并使它们与寄存器访问一样快。

总的来说,我倾向于说:不要担心这个速度。在这个级别进行优化并不重要。尽量避免交换,这将是最快的!

【讨论】:

    【解决方案2】:

    http://en.wikipedia.org/wiki/XOR_swap_algorithm

    大多数现代编译器可以优化掉 naive swap,在这种情况下,naive swap 使用相同数量的 内存和与 XOR 交换相同数量的寄存器,并且位于 至少一样快,而且通常更快。 XOR 交换也少得多 对不熟悉的人可读且完全不透明 技术。在现代 CPU 架构上,XOR 技术是 比使用临时变量进行交换要慢得多。 原因之一是现代 CPU 努力以 通过指令流水线并行。在 XOR 技术中,输入 每个操作都依赖于前一个操作的结果,所以 它们必须严格按顺序执行。

    另请参阅此问题:

    How fast is std::swap for integer types?

    请务必注意,异或交换要求您首先检查两个变量是否引用了相同的内存位置。如果他们这样做了,您最终会将其设置为零。

    【讨论】:

    • 异或交换的比较操作将在我能想到的所有情况下破坏所有性能优势。这就是这项技术的丧钟。
    • 现代 x86 CPU 执行寄存器重命名,我猜此时将删除所有 mov 指令,而无需进入执行端口。因此,对于 CPU 寄存器中的两个变量,与临时变量的交换应该几乎是免费的。
    【解决方案3】:

    XOR 交换并不总是最有效的,因为大多数现代 CPU 架构都尝试并行化指令,但在 XOR 交换中,每一行都取决于先前的结果(不可并行化)。对于临时变量交换,大多数编译器会优化临时变量,最终以天真的方式运行或更快,并使用相同数量的内存。

    另一种交换方式是:

    x = x + y
    y = x - y
    x = x - y
    

    同样,XOR 交换的效率和速度的论点也适用于此。

    编辑:正如斧头所说,如果不小心操作,(+/-)方法也会导致溢出

    【讨论】:

    • 第三种选择存在溢出问题的危险。
    猜你喜欢
    • 2019-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多