[A.B.C.D][E.F.G.H][I.J.K.L] .....
becomes
[D.C.B.A][H.G.F.E][L.K.J.I] ...
Of course, one might use a temporary and swap the bytes.
However, I could imagine that there might be something that
uses DMA or other CPU specific features to do it quickly.
Is there an optimized solution for reverting the byte order of
some chunk of memory? I mean something in the style of
memcpy(...) and memmove(..).
How portable is htonl(...)?
Thanks in Advance.
Frank
--
comp.lang.c.moderated - moderation address: cl...@plethora.net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
According to my documentation, htonl() and friends are part of POSIX, so
they are as portable as POSIX. Of course, on a big-endian system, all of
those byte-swapping functions are no-ops.
--
Kenneth Brody
> Is there an optimized solution for reverting the byte order of
> some chunk of memory? I mean something in the style of
> memcpy(...) and memmove(..).
I don't thinkl so.
> How portable is htonl(...)?
posix + win32 (so very portable) but it will only reverse bytes
on little-endian systems, so it not a portable solution to the
stated proble.
Hi,
I don't know what compiler you are using but here is a solution using
inline assembly with the gnu compiler (gcc) that works with x86 and
x86_64 architectures:
1
2
3 #define xchange(a,b) \
4 asm("\
5 xchg %2, %0\n\t\
6 "\
7 : "=m"(a)\
8 , "=r"(b)\
9 : "r"(b)\
10 );
This macro moves b (%2) in a register (line 9), the instruction 'xchg'
is then used between this register and memory location of 'a'(%0). The
result that is now in the register we have used is now moved to b (line 8).
If you didn't understand any of this, I suggest that you read this
tutorial on gcc's inline assembly:
http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
Note that if you want to port this program to more exotic architectures
(like powerpc), you should also write a full C equivalent of the macro
xchange() and use '#ifdef's to determine which one to use when compiling.
And you must also be aware that this will not work with any variable
bigger than a pointer (sizeof(void*)).
Here is a full example program I just wrote:
1 #include <stdio.h>
2
3 #define xchange(a,b) \
4 asm("\
5 xchg %2, %0\n\t\
6 "\
7 : "=m"(a)\
8 , "=r"(b)\
9 : "r"(b)\
10 );
11
12 int main()
13 {
14 int i;
15 char ch[4] = {'A','B','C','D'};
16 xchange(ch[0], ch[3]);
17 xchange(ch[1], ch[2]);
18 for (i=0; i<4; i++)
19 printf("%c ", ch[i]);
20 printf("\n");
21 return 0;
22 }
I hope this helps.
>Problem reverse byte order of memory chunk, i.e.
>
> [A.B.C.D][E.F.G.H][I.J.K.L] .....
>
>becomes
>
> [D.C.B.A][H.G.F.E][L.K.J.I] ...
>
>Of course, one might use a temporary and swap the bytes.
>However, I could imagine that there might be something that
>uses DMA or other CPU specific features to do it quickly.
Yes. Some DSPs have reversal capability in DMA.
>Is there an optimized solution for reversing the byte order of
>some chunk of memory? I mean something in the style of
>memcpy(...) and memmove(..).
Most people just use htonl, ntohl, etc. I haven't seen an optimized
array version of long word byte reversal, but (assuming an x86 family
processor) you could get half way there quickly using the 16-bit word
shuffle in SSE. That is, you could get from
[A.B.C.D][E.F.G.H][I.J.K.L] ...
to
[C.D.A.B][G.H.E.F][K.L.I.J] ...
in 3 SSE instructions (load,shuffle,store) in groups of 4 or 8 long
words at a time depending on the chip.
From there you have to shift and mask copy the intermediate result
twice to get the final result. I'm not sure how many total operations
offhand, probably about a dozen - I'd have to play with it a bit.
The simplest approach might be just to do 2 passes: a 16-bit shuffle
pass using SSE and then a final pass with htons or ntohs (doesn't
matter which). It might even be faster than trying to do the whole
thing in SSE (at least on a 32-bit chip).
>How portable is htonl(...)?
htonl et al. are frequently implemented as macros rather than
functions. They are completely portable among operating systems that
normally include TCP/IP networking.
If you are working with a simple program loader (DOS) or an embedded
system you may not find them, but they are simple to implement if
necessary.
George
This is more CPU model related of an issue. Not really C.. or
better..
there's surely a clever (optimized in some sense) way of swapping
bytes (data chunks),
and there's an even smarter way if you can demand the operation to
hardware specific
devices!
> Is there an optimized solution for reverting the byte order of
> some chunk of memory? I mean something in the style of
> memcpy(...) and memmove(..).
>
> How portable is htonl(...)?
My practical answer: I use it on windows (minGW and unix gcc and it
works on both)
The C standard does not discuss optimization.
> How portable is htonl(...)?
There is no htonl() in the C standard.
The POSIX htonl() and ntohl() function may or may not reverse the byte
order of the 32-bit integers passed to them, depending on the
implementation. That's what the "h" part means.
DES
--
Dag-Erling Smørgrav - d...@des.no
> Problem reverse byte order of memory chunk, i.e.
>
> [A.B.C.D][E.F.G.H][I.J.K.L] .....
>
> becomes
>
> [D.C.B.A][H.G.F.E][L.K.J.I] ...
>
> Of course, one might use a temporary and swap the bytes.
> However, I could imagine that there might be something that
> uses DMA or other CPU specific features to do it quickly.
Yes, there are such CPU specific variants. But they are CPU
specific and in no way standardized. Usually they imply
programming in assembler.
> Is there an optimized solution for reverting the byte order of
> some chunk of memory? I mean something in the style of
> memcpy(...) and memmove(..).
Nothing standardized. My advice: program a simple version
yourself and only think again about it if measuring results
in the program being too slow and this part the culprit.
> How portable is htonl(...)?
It is available about everywhere the IP protocols are. But
a) on big-endian machines it is a no-op.
b) the calling overhead for using it on pieces of four bytes
may well be higher than what you gain by tapping the knowledge
of the provider of htonl() about your CPU.
--
Greetings,
Jens Schmidt
> Problem reverse byte order of memory chunk, i.e.
>
> [A.B.C.D][E.F.G.H][I.J.K.L] .....
>
> becomes
>
> [D.C.B.A][H.G.F.E][L.K.J.I] ...
>
> Of course, one might use a temporary and swap the bytes.
> However, I could imagine that there might be something that
> uses DMA or other CPU specific features to do it quickly.
>
> Is there an optimized solution for reverting the byte order of
> some chunk of memory? I mean something in the style of
> memcpy(...) and memmove(..).
I do not think optimizing this in one's program is the right thing to do.
>
> How portable is htonl(...)?
It is there in the The Open Group Base Specifications Issue 6:
http://www.opengroup.org/onlinepubs/009695399/toc.htm
So, I doubt if there can be anything more portable than this.