1

假设我有 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),这是最快的,还是有其他更快的?

4

3 回答 3

6

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

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

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

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

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

于 2013-11-08T20:06:53.557 回答
4

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

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

另请参阅此问题:

整数类型的 std::swap 有多快?

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

于 2013-11-08T20:14:53.063 回答
1

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

另一种交换选择是:

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

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

编辑:正如斧头所说,(+/-)方法如果不小心完成也可能导致溢出

于 2013-11-08T20:02:40.360 回答