From what it sounds like, a 64 bit processor means aligning to 64 bits, which means if you have unicode utf-8 stored in there, each 8-bit chunk would take up 64 bits of space. That doesn't really make too much sense, so I think I need to do a bit more to understand exactly how cache aligning works.
But thanks to this great answer to Purpose of memory alignment I see how alignment is beneficial, so I would like to learn what it would mean in practice to implement alignment to a word and to a cache line, together.
For example, take unicode encoded in utf-8. If you were to store that in memory and access it most efficiently in terms of word alignment and cache line alignment, I'm wondering what that would look like / mean.
Some examples are:
- Accessing individual characters.
- Accessing large blocks of text.
From what it sounds like, on a 64-bit machine, you would do this (I'm still a bit confused on how to apply it, which is the reason for the question), where the letters would be unicode encoded in ascii (for the simple case of utf-8, just using ascii):
a b a b a b ...
That would look like:
01100001 01100010 01100001 01100010 01100001 01100010 ...
Or more specifically:
011000010110001001100001011000100110000101100010...
To add more characters to the mix (adding newlines for readability, not adding it to the data):
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
...
abcdefghijklmnopqrstuvwxyz
That's 26 x n, where let's say n is 100, so 2600 8-bit characters (2600 bytes) stacked next to each other. From my understanding, you could say these are "8-bit aligned", or "1-byte aligned".
But now there are two problems:
- Word alignment (and how to figure out what your machine's word alignment is).
- Cache line alignment (assuming all 64-bit machines use 64 bytes as cache line alignment, which is what I've seen from the web).
Since we have 2600 bytes, we could theoretically have 2600 / 64 = 40.625 ≈ 41 cache line aligned chunks, and if the word size was 2 bytes, then 2600 / 2 = 1300 word-aligned chunks.
Now I'm lost, I don't see how we are supposed to access or alternatively organize the data so it takes advantage of these 2 alignment conditions (word and cache line alignment). I already feel like I'm going to create more confusion than is necessary for the question if I try to explain more.
So my question is, how to (a) organize this utf-8 string in memory so that (b) you can take advantage of the 2 alignment conditions, while (c) accessing the data (either individual characters, or chunks between word size and cache line size, or or chunks larger than cache line size). I don't really know what "accessing larger than 64 bits at a time" would mean, since registers are limited like that. So again, don't really understand how the cache alignment works, and interested to know how to align to both conditions properly in this case as a practical example.
Sidenote: I don't need to know exactly how to do it for x86, like which instructions to use and whatnot (unless it is easy / straightforward to describe). I am just looking for at a high level how it works, using x86 as a starting point.
Another way I try looking at this comes after reading:
- Align 8-bit data at any address [don't understand this]
- Align 16-bit data to be contained within an aligned four-byte word
- Align 32-bit data so that its base address is a multiple of four
- Align 64-bit data so that its base address is a multiple of eight
- Align 80-bit data so that its base address is a multiple of sixteen
- Align 128-bit data so that its base address is a multiple of sixteen
Don't quite follow exactly, but say for 8-bit data we align to a 4-byte word. That means it would look like this:
<letter> <empty> <empty> <empty> <letter> <empty> <empty> <empty> ...
So:
a---b---a---b---...
That seems like a lot of wasted space. That would mean that plain text requires 4x the actual size of the text to store in memory, which doesn't seem right.
Finally, when they talk about how if you don't align to the boundaries, it will fetch the extra data, I keep thinking "won't it do a fetch for the empty space anyways". I don't see how if the memory is full or not at a specific point that fetching some extra data would be harmful. That is to say, say the data was like this:
abcdef...
And 4-byte aligned. That means to access a
we would be actually fetching abcd
, to fetch b
it would also fetch abcd
, etc.. But I don't see how that is any different from fetching a---
in this layout:
a---b---c---d---e---f---...