3 ms·
The perf penalty of misaligned loads and stores is incredibly low. JavaScriptCore uses them quite a bit. The penalty is way lower than handling the misalignment
by pizlonator 7y ago
The perf penalty of misaligned loads and stores is incredibly low. JavaScriptCore uses them quite a bit. The penalty is way lower than handling the misalignment by way of a trap, which is what you’d do on Alpha if you had to run some code that was designed to use misalignment. That’s just a fact - the original comment was about how this fact made Alpha a worse target.
I think you’re glossing over a lot of details about the memory model. What the model says about the ordering of dependent loads isn’t a matter of just adding fences later - it’s more fundamental than that. Of Alpha achieved it’s perf advantage thanks to speculating loads then it would have to lose that advantage when it was modernized to current standards. Also, the original comment was about Alpha back then versus Intel—and-others back then, so it’s not interesting to say that Alpha could have just improved - that’s not really responding to the original comment about how hard Alpha was to program.
- 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.