4

为什么数据对齐的正常答案是为了更有效地访问和简化 CPU 的设计。

一个相关的问题及其答案在这里。另一个来源在这里。但他们都没有解决我的问题。

假设 CPU 的访问粒度为 4 个字节。这意味着 CPU 一次读取 4 个字节。我上面列出的材料都说,如果我访问一个未对齐的数据,比如地址 0x1,那么 CPU 必须执行 2 次访问(一个来自地址 0x0、0x1、0x2 和 0x3,一个来自地址 0x4、0x5、0x6 和 0x7)并结合结果。我不明白为什么。为什么当我发出访问地址 0x1 时 CPU 不能从 0x1、0x2、0x3、0x4 读取数据。它不会降低性能并在电路中产生很多复杂性。

先感谢您!

4

4 回答 4

13

它不会降低性能并在电路中产生很多复杂性。

正是我们认为是事实的错误假设真正阻碍了进一步的理解。

在另一个问题中的评论使用了更合适的措辞(“我认为它不会降级”......)

您是否考虑过内存架构并行使用许多内存芯片以最大化带宽?并且特定数据项仅在一个芯片中,您不能只读取最方便的芯片并期望它具有您想要的数据。

现在,CPU 和内存可以连接在一起,这样位 0-7 仅连接到芯片 0、8-15 连接到芯片 1、16-23 连接到芯片 2、24-31 连接到芯片 3。对于所有整数 N ,内存位置 4N 存储在芯片 0 中,4N+1 存储在芯片 1 中,等等。它是每个芯片中的第 N 个字节。

我们来看看每个内存芯片的每个偏移处存储的内存地址

内存芯片 0 1 2 3
抵消

    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 加载,N=0,每个芯片都会报告其内部字节 0,这些位最终都在正确的位置,一切都很好。

现在,如果您尝试从内存位置 1 开始加载一个单词,会发生什么?

首先,我们看看它的完成方式。第一个内存字节 1-3,存储在内存芯片 1-3 的偏移量 0 中,最终在位 8-31,因为这是连接这些内存芯片的位置,即使您要求它们位于位 0-23 中。这没什么大不了的,因为 CPU 可以在内部调整它们,使用用于逻辑左移的相同电路。然后在下一个事务中,存储在内存芯片 0 中偏移量 1 处的内存字节 4 被读入位 0-7 并混合到您想要的位 24-31 中。

注意这里的一些东西。您要求的单词是跨偏移量拆分的,第一个内存事务从三个芯片的偏移量 0 读取,第二个内存事务从另一个芯片的偏移量 1 读取。这就是问题所在。您必须告诉内存芯片偏移量,以便它们可以将正确的数据发回给您,偏移量约为 40 位宽,信号速度非常快。现在只有一组偏移信号连接到所有内存芯片,要为未对齐的内存访问执行单个事务,您需要运行到每个内存芯片的独立偏移(称为地址总线 BTW)。对于 64 位处理器,您将从 1 个地址总线更改为 8 个,增加了近 300 个引脚。在 CPU 使用 700 到 1300 个引脚的世界中,这几乎不能称为“

好吧,这并没有那么糟糕,因为地址总线上一次最多只能有两个不同的偏移量,而且一个总是另一个加一个。因此,您可以在每个内存芯片上使用一根额外的电线,实际上是(读取地址总线上列出的偏移量)或(读取下面的偏移量)这是两种状态。但是现在每个内存芯片中都有一个额外的加法器,这意味着它必须在实际进行内存访问之前计算偏移量,这会降低内存的最大时钟速率。这意味着如果您希望非对齐访问更快,对齐访问会变慢。由于 99.99% 的访问可以对齐,因此这是净损失。

所以这就是为什么非对齐访问被分成两个步骤。因为地址总线由所有涉及的字节共享。这实际上是一种简化,因为当你有不同的偏移量时,你也会涉及不同的缓存线,所以所有的缓存一致性逻辑都必须加倍来处理 CPU 内核之间的两倍通信。

于 2010-10-11T04:47:21.497 回答
0

在我看来,这是一个非常简单的假设。该电路可能涉及多层管道和缓存优化,以确保读取某些内存位。此外,内存读取被委托给内存子系统,这些子系统可能由在性能和设计复杂性方面具有不同数量级的组件构建,以您认为的方式读取。

但是,我确实添加了一个警告,即我不是 cpu 或内存设计师,所以我可能会说瓦罐。

于 2010-10-11T03:55:53.457 回答
0

你的问题的答案就在问题本身。

CPU 的访问粒度为 4 字节。所以它只能以 4 字节的块为单位吞食数据。

如果你访问了地址 0x0,CPU 会给你从 0x0 到 0x3 的 4 个字节。

当您发出指令以从 address 访问数据时,CPU 会将其视为对从( ie. )0x1开始的 4 字节数据的请求。由于 CPU 的粒度,这不能以任何其他方式解释。因此,CPU 从& (ergo,2 次访问)中获取数据,然后将数据 放在一起作为最终结果。0x10x1 to 0x40x0 to 0x30x4 to 0x70x1 to 0x4

于 2010-10-11T04:08:49.767 回答
0

寻址 4 个字节,第一个字节在 0x1 而不是 0x0 左侧未对齐意味着它不是从字边界开始并溢出到下一个相邻字。第一次访问获取到字边界的 3 个字节(假设是 32 位字),然后第二次访问以完成存储器寻址实现的 4 字节 32 位字的模式获取字节 0x4。目标代码或汇编程序有效地为程序员透明地进行第二次访问和连接。如果可能,最好通常以 4 字节为单位保持字边界。

于 2010-11-29T17:14:17.317 回答