首页 > 解决方案 > 为什么 CPU 访问对齐的内存

问题描述

互联网的好人!

在过去的几天里,我一直在阅读有关 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 the beginning of each chunk is aligned in such a way?如果参考上一段中的示例,why exactly CPU cannot read a chunk of 4 bytes starting from 0x1?

据我所知,CPU 非常清楚 0x1 的存在。那么所有的fuzz都是因为内存控制器无法访问从0x1开始的内存块吗?还是因为在某些架构上保留了处理器字中的几个 LSB?或者它们被保留的事实是对齐访问的结果,而不是它的原因(似乎已经是第二个问题,但我会留下它,因为在我写这个问题时我觉得它们是相关的)?

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

标签: memorycpumemory-alignment

解决方案


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

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


推荐阅读