互联网的好心人!
在过去的几天里,我一直在阅读关于CPU如何访问内存的文章,以及如果被访问的对象分散在CPU访问的不同块中,它可能会比预期的要慢。
在非常一般化和抽象的说法中,假设我有一个地址空间从0x0到0xF,一个单元只有一个字节,CPU读取4字节的块内存(也就是说,有一个四字节的内存访问粒度),那么,如果我需要读取一个驻留在单元0x0 - 0x3中的4字节大小的对象,CPU将在一个操作中完成,而如果同一个对象占用单元0x1 - 0x4,那么CPU需要执行两个读取操作(首先在0x0 - 0x3中读取内存,然后在0x4 -0x7中),移位字节并组合两个部分(或者中断,如果它不能进行未对齐访问)。这种情况再次发生,因为CPU可以以4字节块的形式读取内存(在我们的抽象情况下)。让我们还假设,CPU在一个缓存线内进行这些读取,且不需要在两次读取之间更改缓存内容。
因此,在这种情况下,CPU可以读取的每个块的开始驻留在地址是4的倍数的存储单元中(对吗?)。好的,我没有任何关于为什么CPU以块为单位读取的问题,但是如果参考上一段中的例子why exactly CPU cannot read a chunk of 4 bytes starting from 0x1?,why exactly the beginning of each chunk is aligned in such a way?
据我所知,CPU非常清楚0x1的存在。那么,所有的模糊都是因为内存控制器无法访问从0x1开始的内存块吗?或者是因为处理器字中的几个LSB在某些体系结构上是保留的?或者它们被保留的事实是对齐访问的结果,而不是它的原因(似乎这已经是第二个问题了,但我会留下它,因为在我写这个问题的时候,我有一种感觉,它们是相关的)?
这里有一堆关于这个话题的答案(像this和this)和在线文章(像this和this),但是在所有的资源中都有关于现象本身及其后果的很好的解释,但是没有解释为什么CPU不能准确地读取从字节边界之间开始的内存块(或者我看不到它)。