views:

373

answers:

5

I understand what it means to access memory such that it is aligned but I don’t understand why this is necessary. For instance, why can I access a single byte from an address 0x…1 but I cannot access a half word (two bytes) from the same address.

Again, I understand that if you have an address A and an object of size s that the access is aligned if A mod s = 0. But I just don’t understand why this is important at the hardware level.

Thanks!

+10  A: 

Hardware is complex; this is a simplified explanation.

A typical modern computer might have a 32-bit data bus. This means that any fetch that the CPU needs to do will fetch all 32 bits of a particular memory address. Since the data bus can't fetch anything smaller than 32 bits, the lowest two address bits aren't even used on the address bus, so it's as if RAM is organised into a sequence of 32-bit words instead of 8-bit bytes.

When the CPU does a fetch for a single byte, the read cycle on the bus will fetch 32 bits and then the CPU will discard 24 of those bits, loading the remaining 8 bits into whatever register. If the CPU wants to fetch a 32 bit value that is not aligned on a 32-bit boundary, it has several general choices:

  • execute two separate read cycles on the bus to load the appropriate parts of the data word and reassemble them
  • read the 32-bit word at the address determined by throwing away the low two bits of the address
  • read some unexpected combination of bytes assembled into a 32-bit word, probably not the one you wanted
  • throw an exception

Various CPUs I have worked with have taken all four of those paths. In general, for maximum compatibility it is safest to align all n-bit reads to an n-bit boundary. However, you can certainly take shortcuts if you are sure that your software will run on some particular CPU family with known unaligned read behaviour. And even if unaligned reads are possible (such as on x86 family CPUs), they will be slower.

Greg Hewgill
+2  A: 

The computer always reads in some fixed size chunks which are aligned.

So, if you don't align your data in memory, you will have to probably read more than once.

Example

  • word size is 8 bytes
  • your structure is also 8 bytes
  • if you align it, you'll have to read one chunk
  • if you don't align it, you'll have to read two chunks

So, it's basically to speed up.

Etan
A: 

I have very basic(maybe dumb) question here: Why would this memory not aligned in first place? I mean, if you are reading and writing data for given machine, you would follow its alignment rules. On 32-bit system, I will make sure to write data which is 32-bit aligned.

Is that has something to do with network byte ordering?

Jack
This is a theory question.
ChrisDiRulli
It don't have anything to do with network byte ordering.The reason for this is that the data have to be stored in the L1-(Data)-Cache, ond each Cache Line do have a size of 64 Byte (it can be different for another Architecture but the rules are the same), so if you try to save it on the boundary of a Cache line, two Lines have to be read and written because they got modified, and this do cause an increbile performance hit.Because of this data have to be aligned on "boundarys".
Quonux
A: 

Try reading a serial port. The data is 8 bits wide. Nice hardware designers ensure it lies on a least significant byte of the word.

If you have a C structure that has elements not word aligned ( from backwards compatibility or conservation of memory say ) then the address of any byte within the structure is not word aligned.

Tim Williscroft
A: 

The reason for all alignment rules are the various widths of the Cache Lines (Instruction-Cache do have 16 Byte lines for the Core2 Architecture, and the Data-Cache do have 64-Byte Lines for L1 and 128-Byte Lines for L2).

So if you want to store/load data that crosses a Cahce-Line Boundary you need to load and store both Cache-lines, which hits the performance. So you just don't do it because of the performance hit, its that simple.

Quonux