Pointer alignment in libjpeg
From jmorecfg.h:
#define PACK_TWO_PIXELS(l,r) ((r<<16) | l)
#define PACK_NEED_ALIGNMENT(ptr) (((int)(ptr))&3)
#define WRITE_TWO_PIXELS(addr, pixels) do { \
((INT16*)(addr))[0] = (pixels); \
((INT16*)(addr))[1] = (pixels)>>16; \
} while(0)
#define WRITE_TWO_ALIGNED_PIXELS(addr, pixels) ((*(INT32*)(addr)) = pixels
Can someone explain the difference between WRITE_TWO_PIXELS and WRITE_TWO_ALIGNED_PIXELS? If pix开发者_Python百科els is a stack allocated uint32_t and addr & 3 == 0, shouldn't they be equivalent?
Thanks.
WRITE_TWO_PIXELS
and WRITE_TWO_ALIGNED_PIXELS
are equivalent for little endian machines but not for big endian architecture.
[Example edited: thanks to Steve Jessop]
Let, pixels = 0x0A0B0C0D
For big endian machines, WRITE_TWO_PIXELS
work as follows:
---------------------
| 0B | 0A | 0D | 0C |
---------------------
3 2 1 0 <--- addr
where WRITE_TWO_ALIGNED_PIXELS
will write as follows:
---------------------
| 0D | 0C | 0B | 0A |
---------------------
3 2 1 0 <--- addr
In the two macros, the only alignment that matters is the alignment of addr
. As written in the question, they are equivalent if addr
is 32-bit aligned (meaning its low two bits are zero), but only if the target architecture is also little-endian.
On a big-endian machine, the upper 16 bits of pixels
must be written to (INT16*)(addr))[0]
and the lower 16 bits to (INT16*)(addr))[1]
for them to be equivalent.
Without checking my copy of the libjpeg source code, I'd guess that these definitions are either expected to be modified as part of porting the library, or they are already guarded by a declaration of endianness.
If addr
is not 32-bit aligned, then the WRITE_TWO_ALIGNED_PIXELS
macro might cause an exception to be thrown on architectures where unaligned access is not permitted. Of course in some cases, unaligned access is permitted, but is much more expensive than two smaller aligned accesses, and on some other architectures, unaligned access is difficult to distinguish from aligned access.
The two macros exist as a reminder to the author of the library to think about alignment, and to standardize the approach to handling misaligned access so that it can be optimized out when building for platforms where it doesn't matter.
精彩评论