swap() on x86 platforms.
Pal-Kristian Engstad
engstad@squaresoft.com
Mon Jan 5 11:13:00 GMT 1998
Testing on a Pentium revealed that using xchgl for swapping numbers is
not the best way! The reason is that it does not pair very well with
other instructions. On a pentium, if there is a register available,
you should always use:
movl reg1, reg3 ; t = a;
movl reg2, reg1 ; a = b;
movl reg3, reg2 ; b = t;
If a register is not available, it might be faster using the stack:
pushl reg1
pushl reg2
popl reg1
popl reg2
The down-side is of course that you have to use the stack.
Results: (Don't count on them!)
Normal = ~5.5 secs (+/- 0.1)
XOR = ~8.5 secs (+/- 0.1)
XCHG = ~6.0 secs (+/- 0.1)
PUSH/POP = ~5.5 secs (+/- 0.1)
Code:
#include <stdlib.h>
#define FAST_SWAP 1
inline void
swap1 (int & a, int & b)
{
int tmp = a; a = b; b = tmp;
}
inline void
swap2 (int & a, int & b)
{
if (&a != &b) { a ^= b; b ^= a; a ^= b; }
}
inline void
swap3 (int & a, int & b)
{
__asm ( "xchgl %0, %1" : "=r" (a), "=r" (b) : "0" (a), "1" (b) );
}
inline void
swap4 (int & a, int & b)
{
__asm ( "pushl %0; pushl %1; popl %0; popl %1" : "=r" (a), "=r" (b) : "0" (a), "1" (b) );
}
int
main (int argc, char** argv)
{
int data [10240];
for (int i=0; i < 10240; i++)
data[i] = rand();
for (int j=0; j < 10240; j++)
for (int i=0; i < 10239; i++)
{
#if FAST_SWAP == 1
swap1 (data[i], data[i+1]);
#elif FAST_SWAP == 2
swap2 (data[i], data[i+1]);
#elif FAST_SWAP == 3
swap3 (data[i], data[i+1]);
#else
swap4 (data[i], data[i+1]);
#endif
}
}
PKE.
More information about the Gcc
mailing list