Anybody Have a Simple Explanation of Alignment?

I was just wondering anybody here either has a simple explanation of alignment, and why different types have different alignments. I don't need like a super in-depth explanation necessarily if that is hard to come by, but I keep running across things that need to be aligned and I wonder what determines a types alignment and what makes something either properly aligned or not.

I'm just looking for like a kind of quick overview that should be enough to understand general situations a bit better.

Alignment matters because some processors require the pointers it reads from to be aligned in certain manners depending on the kind of data. E.g. the instruction for adding two u32s may require that they are aligned to four bytes. The alignment of primitive types such as integers is typically equal to their size, e.g. u32 is aligned to four bytes. As for compound types such as structs, their alignment is the largest alignment of any field inside the struct.

As for what determines whether something is properly aligned, it is the integer value of the pointer. Alignment by 4 requires the pointer's integer value to be divisible by 4.

2 Likes

OK, well that's pretty simple, thanks again.

One reason why this matters: if a 4-byte integer is 4-byte aligned, then it's only ever on a single cache line. Whereas if it's unaligned it might straddle two of them.

Massive chips like x64 desktop have the extra circuits to handle it, but particularly smaller or power-focused chips would really rather not. So depending on the chip it either breaks or is just slower (sometimes much, sometimes barely) to read unaligned things. (And ptr::{read|write}_unaligned will emit the appropriate instructions that handle unaligned when needed.)

3 Likes

Say we have a struct with two fields. The addresses are x, which has alignment m, and y, which has alignment n. That is, x is one of 0, m, 2m, 3m, 4m etc. and y is one of 0, n, 2n, 3n, 4n etc. In short there are (non-negative) integers a,b, such that x=am and y=bn.

Now we want to shift the base address of the struct by the least amount s. By definition this is the alignment of the struct. Because the addresses need to be well aligned afterwards, there must be some integers a',b' with x+s=a'm and y+s=b'n. So

s = a'm - x = a'm - am = (a'-a)m,
s = b'n - y = b'n - bn = (b'-b)n.

This means, s must divisible by m and n. Thus s is the least common multiple of m and n. Especially if m,n are powers of two, s=max(m,n).

2 Likes