Memory alignment on a 32-bit Intel processor

Intel's 32-bit processors such as Pentium have 64-bit wide data bus and therefore fetch 8 bytes per access. Based on this, I'm assuming that the physical addresses that these processors emit on the address bus are always multiples of 8.

Firstly, is this conclusion correct?

Secondly, if it is correct, then one should align data structure members on an 8 byte boundary. But I've seen people using a 4-byte alignment instead on these processors.

How can they be justified in doing so?


Solution 1:

The usual rule of thumb (straight from Intels and AMD's optimization manuals) is that every data type should be aligned by its own size. An int32 should be aligned on a 32-bit boundary, an int64 on a 64-bit boundary, and so on. A char will fit just fine anywhere.

Another rule of thumb is, of course "the compiler has been told about alignment requirements". You don't need to worry about it because the compiler knows to add the right padding and offsets to allow efficient access to data.

The only exception is when working with SIMD instructions, where you have to manually ensure alignment on most compilers.

Secondly, if it is correct, then one should align data structure members on an 8 byte boundary. But I've seen people using a 4-byte alignment instead on these processors.

I don't see how that makes a difference. The CPU can simply issue a read for the 64-bit block that contains those 4 bytes. That means it either gets 4 extra bytes before the requested data, or after it. But in both cases, it only takes a single read. 32-bit alignment of 32-bit-wide data ensures that it won't cross a 64-bit boundary.

Solution 2:

Physical bus is 64bit wide ...multiple of 8 --> yes

HOWEVER, there are two more factor to consider:

  1. Some x86 instruction set are byte addressed. Some are 32bit aligned (that's why you have 4 byte thing). But no (core) instruction are 64bits aligned. The CPU can handle misaligned data access.
  2. If you care about the performance, you should think about the cache line, not main memory. Cache lines are much wider.