Alignment Requirement

A memory address  is -byte aligned when  is a multiple of  (where  is a power of 2)
A data is naturally aligned when data’s memory address is a multiple of the data size

The effects of performing an unaligned memory access vary from architecture to architecture:

  • On some architectures unaligned accesses may not be supported
  • Unaligned accesses may be non-atomic
  • Accesses that cross a cache line boundary may cause a performance penalty because multiple lines need to be fetched
  • Accesses that cross a page boundary may cause an even bigger performance penalty because multiple pages need to be fetched
  • A DRAM typically supports only aligned bursts

Satisfying Alignment Requirements

Alignment is enforced by making sure that every data type is organized and allocated in such a way that every object within the type satisfies its alignment restrictions

  • Initial address of the object must be aligned. Starting address for any block generated by a memory allocator must be aligned
  • Every field inside the object must be aligned
  • Size of the object must be aligned to satisfy alignment for arrays of objects
  • Stack frame must be aligned

For example, given the following struct:

struct S {
	T1 f1
	T2 f2
	...
	Tn fn
}

The compiler ensures alignment by inserting padding, so that:

  • Any pointer p of type struct S* points to an address that is a multiple of the size of the largest element type
  • Each field fi is aligned, meaning the address of fi is a multiple of the size of Ti
  • The total size of struct S is a multiple of the size of the largest element type, ensuring proper alignment for arrays of S

The compiler uses .align directives in the assembly code to enforce alignment for global data.

References