Pointer alignment to memory

Pointer alignment to memory

programming
c-programming, pointer alignment

Pointer alignment to memory #

Why do you need to alignment at all? #

In terms of memory accesses, there are two types of CPUs - ones that support unaligned memory access and others which don’t. On most architectures, memory accesses(load/store instructions) support different byte sizes 1 byte, 2 byte, 4 byte, 8 byte, 16 byte etc. Unaligned memory access is a load/store that is trying to access an address location which is not aligned to the access size.

Quoting from the kernel documentation here are reasons why unaligned accesses are bad: #

The effects of performing an unaligned memory access vary from architecture to architecture. It would be easy to write a whole document on the differences here; a summary of the common scenarios is presented below:

  • Some architectures are able to perform unaligned memory accesses transparently, but there is usually a significant performance cost.
  • Some architectures raise processor exceptions when unaligned accesses happen. The exception handler is able to correct the unaligned access, at significant cost to performance.
  • Some architectures raise processor exceptions when unaligned accesses happen, but the exceptions do not contain enough information for the unaligned access to be corrected.
  • Some architectures are not capable of unaligned memory access, but will silently perform a different memory access to the one that was requested, resulting in a subtle code bug that is hard to detect!

It should be obvious from the above that if your code causes unaligned memory accesses to happen, your code will not work correctly on certain platforms and will cause performance problems on others.

Aligning pointers to N-bit memory accesses #

While learning to implement malloc, I wanted to have the pointers align to either 4byte or 8byte memory. A couple of implemntation that I came across that worked for me are as follows: For a 4byte alignment using ((i+3) & ~3) where i is the pointer, aligns this to 4bytes, similarly for 8byte alignment we can use ((i+7) & ~7).

((num + (align - 1)) & ~(align - 1)) . would be a generic way to write.