Swapping two arbitrary variables

Started by
14 comments, last by Nemesis2k2 19 years, 7 months ago
Here is really basic assembly for a normal swap, using two registers (found it by looking elsewhere on GameDev, posted by Prosper/LOADED):
inline void swap(int& a, int& b){  asm  {    mov   eax, a    mov   ebx, b    mov   b, eax    mov   a, ebx  };}

You'll notice that the first two instructions are completely independent. This means that the processor can roughly do them at the same time. The second two instructions are also completely independent. They can be done at roughly the same time as well. The second two obviously have to wait for the first two to complete of course, but each pair can occur simultaneously. Modern processors have been doing this for quite a while, and they and compilers get better at it all the time.

The XOR method does not allow this. The second operation needs to wait for the first operation to complete before it can start. The third operation also needs to wait for the second operation to complete before it can start. All this waiting means that a lot of the CPU is sitting there unused.

Graphically, the first one would look like this:
[**** OPERATION 1 ****]    [**** OPERATION 3 ****]    [**** OPERATION 2 ****]    [**** OPERATION 4 ****]

The second one (XOR) would look more like this:
[**** OPERATION 1 ****][**** OPERATION 2 ****][**** OPERATION 3 ****]
So you can see how the XOR ends up taking longer, even though it has one less operation.
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke
Advertisement
Creating a temporary is actually faster than using XOR?! I thought bitwise operations were supposed to be really fast.

http://www.gamedev.net/reference/programming/features/bitwise/page4.asp
(ctrl + f "swapping variables")

^ Where I got my information from.
Quote:Original post by load_bitmap_file
Creating a temporary is actually faster than using XOR?! I thought bitwise operations were supposed to be really fast.

http://www.gamedev.net/reference/programming/features/bitwise/page4.asp
(ctrl + f "swapping variables")

^ Where I got my information from.
Well, they are, and movs are just as fast. So basically if you do something like this:
;; Swap eax and ebxmov edx, eax ; u pipe \__ 1 clock!mov ecx, ebx ; v pipe /mov ebx, edx ; u pipe \__ 1 clock!mov eax, ecx ; v pipe /
They're perfectly paired, no stalls.
;; Swap eax and ebxxor eax, ebx ; u pipe --- 1 clock!;; STALL, not paired, write after read (ebx)xor ebx, eax ; u pipe --- 1 clock!;; STALL, not paired, write after read (eax)xor eax, ebx ; u pipe --- 1 clock!
Now, in the first method (temp swap) the C compiler will likely notice that you're swapping with a temp and replace it with xchg eax, ebx if it's relatively smart. A not-so-smart compiler might ignore the XOR-swap and just turn it into a bunch of XORs (ick).
;; Swap eax and ebxxchg eax, ebx ----------- 1 clock!
Very nice.
Ra
Also note that the hack shown by CGameProgrammer breaks when the size of the type you are passing in is different from sizeof(int) (note that aligment can also change the behavior of it).

i.e. calling the XOR swap with char could enp up modifying bits that you do not own.

It is interesting what was mentioned about performance, even though I do not think swap will show up on as a hotspot on a profile run.

My take on this (on the C++ side), use std::swap, use the temporary variable, and do not worry about its performance until you have profiled and found it to be something that is slowing down your application.

For C# there is no reliable way to do a swap that works across reference and value types.
When I said 'better' I actually meant cleaner. I don't like needing three lines of code to do things that I should be able to do with 1.
I'd advise everyone not to try and optimise something like this. Stick with the traditional way of creating a temporary variable. That's a method compilers can recognise, and they can do the optimisation for you. Chances are, they'll choose the best method for the situation. At any rate, it's not your job to worry about it, it's theirs.

This topic is closed to new replies.

Advertisement