What is the quickest way to reverse the endianness of a 16 bit and 32 bit integer. I usually do something like (this coding was done in Visual Studio in C++):
union bytes4
{
__int32 value;
char ch[4];
};
union bytes2
{
__int16 value;
char ch[2];
};
__int16 changeEndianness16(__int16 val)
{
bytes2 temp;
temp.value=val;
char x= temp.ch[0];
temp.ch[0]=temp.ch[1];
temp.ch[1]=x;
return temp.value;
}
__int32 changeEndianness32(__int32 val)
{
bytes4 temp;
temp.value=val;
char x;
x= temp.ch[0];
temp.ch[0]=temp.ch[1];
temp.ch[1]=x;
x= temp.ch[2];
temp.ch[2]=temp.ch[3];
temp.ch[3]=x;
return temp.value;
}
Is there any faster way to do the same, in which I don't have to do so many calculations?
Who says it does too many calculations?
What does your compiler produce?
At least in Visual C++, you can use _byteswap_ulong() and friends: http://msdn.microsoft.com/en-us/library/a3140177.aspx
These functions are treated as intrinsics by the VC++ compiler, and will result in generated code that takes advantage of hardware support when available. With VC++ 10.0 SP1, I see the following generated code for x86:
Why aren't you using the built-in
swab
function, which is likely optimized better than your code?Beyond that, the usual bit-shift operations should be fast to begin with, and are so widely used they may be recognized by the optimizer and replaced by even better code.
Because other answers have serious bugs, I'll post a better implementation:
None of the compilers I tested generate
rolw
for this code, I think a slightly longer sequence (in terms of instruction count) is actually faster. Benchmarks would be interesting.For 32-bit, there are a few possible orders for the operations:
I used the following code for the 16bit version swap function:
With g++ (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5 the above code when compiled with
g++ -O3 -S -fomit-frame-pointer test.cpp
results in the following (non-inlined) assembler code:The next code is equivalent but g++ is not as good at optimizing it.
Compiling it gives more asm code: