4 ms·
> The perf penalty of misaligned loads and stores is incredibly low. Yeah, this. You might as well think of them as free in most scenarios involving small rea
by BeeOnRope 7y ago
> The perf penalty of misaligned loads and stores is incredibly low.
Yeah, this.
You might as well think of them as free in most scenarios involving small reads and writes. If there is some small advantage to misalignment (often, reduced memory use through better packing), do it!
The cross-line penalty would occur only for 3 out of 64 alignments for a 4-byte load: less than 5% of the time, and then the penalty is small.
That % is more or less worst case in well designed code [1]. Sometimes you can do misaligned loads that you guarantee will never cross. A common example is a misaligned LUT where the values overlap. E.g., given n, you want to load 8 bytes with:
[n, n+1, n+2, ..., n+7]
Let's say n ranges from 0 to 15. A traditional aligned LUT would have 16x 8-byte values, one for each n (128 bytes). You could also do it with a single 23 byte LUT, running from 0 to 22, and a misaligned load into that LUT at byte position n. As long as you align the LUT itself (e.g., to 32 bytes), you will never cross a line.
For large accesses, things become less clear. After all, a 512-bit AVX-512 access is guaranteed to cross if it is misaligned, and 256-bit access randomly distributed cross half the time, etc. Vectorized code is also the type of code that may be written to approach the 2/1 load/store per cycle limit, so it really pays to try to get alignment for any type of non trivial loop.
---
[1] Specifically, this is the crossing % you would get if you could assume nothing about the distribution of the accesses, i.e., they are uniformly randomly distributed. If you know something about the expected alignment, then you can shift everything to make crossing less likely.