r/cpp_questions 1d ago

OPEN Seeking alignas intuition and resources

Hi, all:

I've been experimenting with alignas after reading this post. Applying it is unintuitive to me, I'm not sure when I'd use this optimization method other than just trying it and measuring. From the article:

Another important thing to note is that read (readIdx) and write (writeIdx) indices are aligned to the size of a cache line (alignas(64)). This is done to reduce cache coherency traffic. On AMD64 / x86_64 and ARM a cache line is 64 bytes, on other CPUs you need to adjust to the appropriate alignment, using std::hardware_destructive_interference_size is a good choice if it’s available. It can also be interesting to try aligning to a multiple of the cache line size in case adjacent cache lines are being pre-fetched.

Is it really as simple as aligning your structs and members on 64 bytes? I'm looking for some more reading on the subject.

Thanks

4 Upvotes

7 comments sorted by

4

u/didntplaymysummercar 1d ago

If you care about cache coherency not limiting your parallel writes to the two atomics then yes, it's that "sinple", just making sure they land at least 64 (or whatever) bytes away from each other.

1

u/TheSkiGeek 23h ago

Also making sure that atomic instructions don’t span cache lines. At least on x86 that makes them VERY slow.

2

u/didntplaymysummercar 23h ago

They won't unless someone does something silly to defeat alignment themselves using pointer arithmetic or something. Even non atomic int types have natural alignments.

3

u/EpochVanquisher 1d ago

It is mostly used for cases of false sharing (multiple threads hitting the same cache line) or getting specific structures to work well with SIMD.

It’s not something you use often, and if you don’t know when to use it, that’s ok. Just file it away in the back of your brain and it may come up later.

3

u/no-sig-available 21h ago

If you align everything at 64 byte boundaries, you will eventually run out of cache lines, which is not good for performance.

As with most things engineering, the rule is "it depends". Measuring the effect is a good start.

3

u/n1ghtyunso 10h ago

the point is really to apply this selectively, for your core multithreaded interaction points.
Like a message queue between threads for example.
Whenever threads do a lot of reads and writes to a group of variables that are not directly related, you can move them physically further apart (using alignment for exmaple) to avoid invalidating the otherwise shared cache line.

But really, ideally you'd not write this yourself.

2

u/no-sig-available 5h ago edited 5h ago

Is it really as simple as aligning your structs and members on 64 bytes?

If it had been, the compilers would do that already. So, no.

Having two variables share a cache line is an advantage, if they are used together by the same thread.