为什么需要进行内存对齐?

8

可能是重复问题:
内存对齐的目的

我读了一些关于内存对齐的文章,理解到从正确对齐的内存(例如2字节对齐)中,我们可以快速地一次性获取数据。

但是如果我们有像单个硬件部件一样的内存,那么为什么不能直接从该位置读取2字节,就像这样:enter image description here

我思考了一下。我认为,如果内存是奇偶银行之类的,则该理论将适用。

enter image description here

我错过了什么吗?


硬件将数据存储在1、2、4字节的块中(取决于硬件类型),因此,如果您想要来自不同块的两个字节,则必须执行两个操作。 - Johan Lundberg
有些硬件会直接拒绝在两个周期内进行访问。未对齐的内存访问是否总是会导致总线错误? - Bo Persson
3个回答

15

你的图片描述了人类如何可视化计算机内存。

实际上,将内存看作巨大的二进制矩阵,每个矩阵列都有一个“读写器”,可以读/写该列中的任何位。每个矩阵行都有一个“选择器”,可以选择读/写器要读/写的特定位。

因此,该读写器可以一次性读取整个选定的矩阵行。这一行的长度(矩阵列数)定义了一次能够读取多少数据。例如,如果你有64列,则你的内存控制器可以一次性读取8个字节(但通常可以读取更多)。

只要保持数据对齐,就可以减少需要访问内存的次数。即使你只需要读取两个位,但它们位于不同的行上,你也需要进行两次内存访问,而不是一次。

此外,还有一个完全不同的问题,那就是写入

正如你可以读取整个行,你也可以写入整个行。如果你的数据没有对齐,当你写入不完整的行时,你需要进行读-修改-写操作(读取行的旧内容,修改相关部分,然后写入新内容)。


你的“读者”抛物线非常清晰!谢谢 - Aubin

14

通常,从内存中读取的数据会通过一组与总线宽度匹配的电线传递到处理器上。例如,如果总线宽度为32位,则有32根数据电线从总线进入处理器(还有其他控制信号的电线)。

在处理器内部,各种电线和开关将这些数据传递到所需的位置。如果将32位对齐的数据读入寄存器中,则电线可以直接将数据传递到寄存器(或其他保存位置)。

如果将8位或16位对齐的数据读入寄存器中,电线可以以同样的方式传递数据,而寄存器中的其他位被设置为零。

如果将8位或16位不对齐的数据读入寄存器中,则电线无法直接传递数据。相反,必须进行位移:它们必须经过另一组电线,以便可以“移动”到与进入寄存器的电线对齐。

在某些处理器中,设计人员已经添加了额外的电线和开关来完成这个移动。从芯片角度来看,这可能非常昂贵。您需要大量的额外电线和开关,才能够将任何可能的不对齐字节移动到所需位置。由于这样做很昂贵,在一些处理器中,并没有一个完整的移位器能够立即进行所有的位移。相反,移位器只能每个CPU周期移动几个字节,需要数个周期来移动多个字节。在一些处理器中,根本没有任何电线可用于此,因此所有的加载和存储都必须对齐。


4
在第一种情况下(单个硬件),如果您需要读取2个字节,那么处理器将不得不发出两个读取周期,这是因为内存是按字节寻址的,即每个字节都有一个唯一的地址。
将内存组织成银行有助于CPU在单个读取周期中获取更多数据到寄存器中。这种技术有助于减少读取周期 - 与CPU的处理能力相比,这是一个非常缓慢的过程。因此,对于单个读取周期,您可以读取更多的数据。

是的,所以在单一内存硬件中,“内存对齐很好”的概念毫无意义。我相信每个字节无论是在银行内存还是单通道内存中都有唯一的地址。 - Ashish Negi
是的,每个字节都有一个唯一的地址。你可以参考这篇文章http://www.geeksforgeeks.org/archives/9705。 - Manik Sidana

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接