Memory 为什么CPU访问对齐内存

Memory 为什么CPU访问对齐内存,memory,cpu,memory-alignment,Memory,Cpu,Memory Alignment,互联网上的好人 在过去的几天里,我一直在读CPU是如何访问内存的,如果被访问的对象分布在CPU访问的不同块上,那么访问内存的速度会比预期的慢 在一个非常广义和抽象的词中,如果我,比方说,有一个从0x0到0xF的地址空间,一个单元是一个字节,CPU以4字节的块读取内存(也就是说,有一个四字节的内存访问粒度),那么,如果我需要读取一个位于单元0x0-0x3中的4字节大小的对象,CPU将在一次操作中完成,而如果同一个对象占用单元0x1-0x4,则CPU需要执行两个读取操作(先读取0x0-0x3中的内存

互联网上的好人

在过去的几天里,我一直在读CPU是如何访问内存的,如果被访问的对象分布在CPU访问的不同块上,那么访问内存的速度会比预期的慢

在一个非常广义和抽象的词中,如果我,比方说,有一个从0x0到0xF的地址空间,一个单元是一个字节,CPU以4字节的块读取内存(也就是说,有一个四字节的内存访问粒度),那么,如果我需要读取一个位于单元0x0-0x3中的4字节大小的对象,CPU将在一次操作中完成,而如果同一个对象占用单元0x1-0x4,则CPU需要执行两个读取操作(先读取0x0-0x3中的内存,然后读取0x4-0x7中的内存),移动字节并合并两个部分(如果无法进行未对齐访问,则中断)。这种情况再次发生,因为CPU可以读取4字节块的内存(在我们的抽象示例中)。我们还假设,CPU在一条缓存线内进行这些读取,并且不需要在读取之间更改缓存的内容

因此,在这种情况下,CPU可以读取的每个块的开头都位于一个内存单元中,该单元的地址是4的倍数(对吗?)。好的,我对CPU为什么以块的形式读取没有任何疑问,但是
为什么每个块的开头都是这样对齐的?
如果参考上一段中的示例,
为什么CPU不能读取从0x1开始的4字节块?

正如我所理解的,CPU非常清楚0x1的存在。那么,所有的模糊都是因为内存控制器无法访问从0x1开始的内存块而发生的吗?或者是因为在某些体系结构上保留了处理器字中的几个LSB?或者,它们被保留的事实是一致访问的结果,而不是其原因(这似乎已经是第二个问题了,但我会留下它,因为在我写这个问题时,我感觉它们是相关的)


这里有很多关于这个主题的答案(比如和)和在线文章(比如和),但是在所有的资源中都有关于现象本身及其后果的很好的解释,但是没有解释为什么CPU不能读取从字节边界“中间”开始的内存块(或者我可能看不到).

考虑一个简单的CPU。它有32个RAM芯片。每个芯片提供一位内存。CPU产生一个地址,将其传递给32个RAM芯片,然后返回32位。第一个RAM芯片保存字节0、4、8、12、16等的位0。第二个RAM芯片保存字节0、4、8、12、16等的位1。第九个RAM芯片保存字节1、5、9、13、17等的位0


因此,您可以看到,它们之间的32个RAM芯片可以产生字节0到3的0到7位,或字节4到7,或字节8到11等。它们无法产生字节1到4。

这一切取决于处理器的设计。有些,特别是x86,可以很好地进行非对齐访问,但速度会慢一些。@MarkRansom感谢您的评论!正如我所理解的,在这种情况下,可能会有两个(或更多)对齐的访问来覆盖所需的内存,而不是一个未对齐的访问本身。对吗?是的,这是正确的-这就是为什么我说它会慢一些,因为需要两次实际访问。谢谢你的回答。我从你的话中了解到,内存硬件本身的一个固有特性是,它只能提供从特定地址开始的数据,而不是CPU无法请求从特定地址开始的内存。换句话说,一般来说,CPU可以请求从1到4的字节,但内存控制器会像“不,我可以给你0-3和4-7”。对吗?