为什么要数据对齐?
所谓数据对齐是指访问数据的地址要满足一定的条件,能被这个数据的长度所整除。 例如,1字节数据已经是对齐的,2字节的数据的地址要被2整除,4字节的数据地址要 被4整除。
但为什么要数据对齐呢?简单地说,数据对齐是为了读取数据的效率。假如说每一次 读取数据时都是一个字节一个字节读取,那就不需要对齐了,这跟读一个字节没有什 么区别,就是多读几次。但是这样读取数据效率不高。为了提高读取数据的带宽,现 代存储系统都采用许多并行的存储芯片来提高读取效率。以自然字长为4个字节的机器 为例。
memory chip 0 1 2 3 offset 0 0 1 2 3 1 4 5 6 7 2 8 9 10 11 N 4N 4N+1 4N+2 4N+3
如上图所示,地址0-3的4字节数据都存储在4个不同的芯片上。CPU的bits 0-7连上芯 片0,bits 8-15连上芯片1,bits 16-23连上芯片2,bits 24-31连上芯片4。
如果从地址0读取4字节数据,4个存储芯片都从各自的地址0读出数据,而且位置也是 正确的。这4个字节的读取可以并行地进行,因此带宽是一次读取一个字节的4倍。
假如要从地址1读取4字节数据会发生什么呢?首先,读取的数据位置不正确。从芯片1 读取的数据应该放在bits 0-7,它却对应CPU的bits 8-15。从芯片2,3,0读取的数据 也是一样。这并不是什么大问题,CPU可以把读入的数据循环左移8比特来把它们放置 在正确的位置上。问题在于,这一次发给4个芯片的地址不一样,给芯片1,2和3的地 址是0,给芯片0的地址是1。也就是说给每一个芯片的地址都不一样,这就需要多根地 址总线。32位的CPU就需要4个地址总线,每个地址总线需要用到CPU的至少32个引脚, 也就是必须要100多根引脚。而通常32位的CPU也就400多个引脚。这当然会增加CPU与 内存接口的复杂性(也可能会有其它的方案解决这个问题,但最终都会使接口变得更 复杂,还可能会降低效率)。但是增加这个复杂性是不值得。由于大多数数据访问都 可以做成对齐的(编译器通常会使数据对齐),因此为了使极少数的不对奇访问速度 更快而使CPU与内存的接口变的更复杂,