cachingmemorymemory-alignmentcpu-cacheprocessor

Should I align data to their data type or cpu cache line size?


Data is usually aligned with its own data type, i.e a 32-bit int is usually aligned to 4 bytes, this makes loading/storing them more efficient for the processor.

Now when does cache line alignment come into play? If x64 cache line size is 64 bytes then should I make each data aligned to 64 bytes? that seems like a waste of memory.

What is the relation between these two types of alignment? and if cpu interaction with cache line is always 64-bits at a time then why does data type alignment even matter?


Solution

  • Data is usually aligned with its own data type, i.e a 32-bit int is usually aligned to 4 bytes, this makes loading/storing them more efficient for the processor.

    On some architectures, it's not so much a matter of efficiency but of your code working at all. Attempting to access a misaligned object can produce a trap. Also, it is not necessarily the case that the natural alignment for a given data type is the same as the size of that data type. The natural alignment cannot, in practice, be larger than the type's size, but it can be smaller.

    Now when does cache line alignment come into play? If x64 cache line size is 64 bytes then should I make each data aligned to 64 bytes? that seems like a waste of memory.

    Indeed so. And counterproductive, too. One of the ways cache helps, and among the reasons that cache line size is generally several times larger than the machine's native word size, is that an access to a word at one address is very frequently followed by accesses to words at nearby addresses. Thus, one often provides for future reads by loading the cache line for the current one. If every object were aligned to the cache line size (supposing that were even feasible), you would thereby throw away a lot of the advantage otherwise obtained by caching.

    What is the relation between these two types of alignments?

    Cache lines are ordinarily aligned more strictly than any native data type, so an object aligned to a cache line boundary will also be aligned properly for its data type. That also means that no naturally aligned object of native data type will straddle two cache lines. Other than that, I'm not really sure what you might asking.

    and if cpu interaction with cache line is always 64-bits at a time then why does data type alignment even matter?

    I guess you meant 64 bytes, not bits. But the question is anyway ill-conceived. Any involvement of cache is a detail of CPU interaction with memory. And because cache line alignment is stricter than any native data type's, an object has the same alignment in cache as it has in main memory. Caching and alignment are pretty much orthogonal matters.

    Overall, aligning objects naturally for their data types is a fairly important consideration (but not necessarily essential), but to a first approximation, aligning individual objects to cache lines is of no particular import. Cache and cache lines become important in the context of patterns of access to multiple objects. Ideally, one will structure the data and code so that cache does not get invalidated or flushed (or, therefore, reloaded) any more than necessary, but that has little to do with the alignment of individual objects.