11 comments

[ 4.4 ms ] story [ 38.3 ms ] thread
Data alignment is not just for memory: it is still very important on storage - especially SSDs.

Even in 2019, finding out the erase size is still a problem.

Personally, I run a benchmark script whenever I provision a server. It explore a small set of values to find the ideal filesystem parameters.

It is not as complete as doing several iteration of random 4k iops with fio on the full partition, but a good enough rule of thumb to avoid misconfigurations.

Would you mind sharing your benchmark script?
Oh, the 68K, PPC and Altivec. Brings back memories.

However, it really is just memories. Nowadays, total memory consumption usually trumps alignment, so it tends to be better to pack your data as tightly as possible and let the CPU extract the bits it needs, which particularly x86 is very good at. Packing is particularly effective if manage to get everything onto a cache line.

Reason being the gulf between CPU and memory performance. If you save just one memory access you can pay for that with a lot of internal CPU operations.

Conversely, if you have a structure shared between different threads/cores, you probably want to make sure they do not share a cache line.

And yes, atomics should definitely be aligned.

ARM still requires aligned access, I believe. And splitting a single variable across word or cache boundaries is still a bad idea.

More interesting is the question of whether to do traditional C struct style "row first" data layout, or whether to do "column first" data layout which may be better for use with SIMD.

> ARM still requires aligned access, I believe.

ARMv7 supports unaligned access but not on all operations (e.g. LDM or STM don't support it). And the operation will simply be split into multiple aligned accesses, which are not necessarily atomic.

ARM64 further expands this, according to ARM

> Except for exclusive and ordered accesses, all loads and stores support the use of unaligned addresses when accessing normal memory.

On ARMv5, some operations could be given unaligned addresses but would round them down, and possibly rotate the result.

ARMv6 is/was switchable between ARMv7 and ARMv5 behaviour.

Also ARMv7+ can be configured to fault on all unaligned access.

https://blog.einval.com/2019/01/07#rebuilding_on_arm64 says the Linux kernel sends SIGBUS on unaligned accesses on arm64.
That is for arm32 userspace binaries being run under an arm64 kernel, and applies only to the handful of instructions which in Armv8 still generate alignment faults. With an arm32 kernel you could configure the kernel to fix those up as well; with an arm64 kernel you cannot.

This only really matters for broken programs which do unaligned accesses without telling the compiler about it (which can also trip you up, though more rarely, under x86, if the compiler decides to use a simd instruction). As Steve says, it only affects a really tiny set of programs, which can have their bugs fixed.

The newer "big ARMs" can do unaligned access much the same way as x86, because they have a similar cacheline-at-once microarchitecture.
That agrees with my experience: everything within a cacheline is just as fast, it's only accesses which cross one that are slower; and unless those odd ones are the only accesses that occur, it's better for memory bandwidth to pack everything together.

which particularly x86 is very good at

That's largely because x86 never had aligned instructions, and whose sizes are simply multiples of bytes, so quite early in its development it already ahd efficient ways of extracting the needed set of bytes from memory regardless of alignment.

> everything within a cacheline is just as fast,

Yep. Which makes you wonder if maybe this sort of thing should be surfaced somehow.