2014-04-03 21 views
2

允许交换2个变量。通过mov交换变量的成本,xor

int temp = a; 
a = b; 
b = temp; 

下面是一些半优化ASM伪代码:

mov eax, dword ptr [rbp+4] 
mov ebx, dword ptr [rbp+8] 
mov dword ptr [rbp+8], eax 
mov dword ptr [rbp+4], ebx 

难道是更快的海誓山盟,以异或对象?

a ^= b ^= a ^= b; 

ASM伪代码:

mov eax, dword ptr[rbp+4] 
xor eax, dword ptr[rbp+8] 
xor dword ptr[rbp+8], eax 
xor eax, dword ptr[rbp+8] 
xor dword ptr[rbp+8], eax 
mov eax, dword ptr[rbp+4] 

以下哪种会更快? (欢迎客人)

+1

它也将取决于它在哪个CPU上运行。 – theunamedguy

+0

这个问题没有实际意义,因为没有一条指令可以直接操作两个内存操作数。 –

+1

真的吗?那么在任何情况下都排除'xchg',我会将我的伪代码重新编写为'mov'来首先注册 –

回答

2

把它拉到两个寄存器,然后回写内容可能是最快的解决方案。四个存储周期,四条指令,两个寄存器。假设数据必须开始并返回到公羊,那么你一般无法打败这种方法。假设你可以为源和目的地做内存,四个xor是每个异或三个周期,12个内存周期,这是一个明确的失败者。使用寄存器来避免两个mem操作数只是增加了更多的指令。

您的asm伪代码是6个内存循环。 6条指令一个注册。四个周期,四个指令两个寄存器可能更便宜。现在如果你必须做两个存储周期来释放这些寄存器,它将变成6个周期。在这最后一个将是一个额外的释放寄存器,所以7.6仍然比7和5的指令便宜,比7便宜,指令的大小不计算在内,但增加了内存周期,虽然提取可能以有效的方式完成(在大小合适的块中)。

如果数据已经在寄存器中,那么使用第三个寄存器并且执行三条指令tmp = a,a = b,b = tmp是三个操作三个寄存器和最快的。但是,如果你只是不能备份一个寄存器,那么四个xors会更快。

这就是所有通用的高级视图,有可能是处理器和缓存情况等,这可能会使一个解决方案看起来更快,而不是最终确定为一个测试更快,但可能一般取决于具体情况。

+0

x86有'xchg'指令来交换值,所以你不需要另一个免费的临时寄存器 –

+0

如果它全部在寄存器中,那么你去那是最好的方法,如果它必须开始并以ram结尾,然后交换注册内容只是浪费的指令。 –

2

在任何机器上,没有任何理由说明Xor方法会更快。

两种方法都需要执行两次读取和两次写入,而Xor方法具有ALU +内存开销。

0

在支持寄存器移动消除(例如 - IvyBridge或更新版本)的处理器上,如果可以使编译器将这些值保存在寄存器中,则最快的方法应该是第一种方法(使用temp变量)(您必须检查生成的程序集以确保)。

这样,你不仅避免了内存访问(虽然读写后应该得到内部转发,但你仍然积聚在存储单元延迟),也避免执行等待时间。 CPU只需在无序寄存器重命名器中自行切换寄存器的指针。

即使没有移动消除,注册专用移动应该更快。内存单元必须执行很多限制(冲突检查,高速缓存查找等),更长的管道和更少的带宽才能正常执行。