26

我听说很多数据应该在内存中正确对齐以提高访问效率。CPU 在字边界上访问内存。

所以在下面的场景中,CPU 必须进行 2 次内存访问才能获得一个单词。

Supposing: 1 word = 4 bytes

("|" stands for word boundary. "o" stands for byte boundary)


|----o----o----o----|----o----o----o----|   (The word boundary in CPU's eye)
           ----o----o----o----              (What I want to read from memory)

为什么会发生这种情况?CPU只能在字边界读取的根本原因是什么?

如果 CPU 只能访问 4 字节的字边界,地址线应该只需要 30 位,而不是 32 位宽度。因为在 CPU 的眼中,最后 2 位始终为 0。

加 1

更重要的是,如果我们承认 CPU 必须在字边界处读取,为什么边界不能我想要读取的位置开始呢?似乎边界在 CPU 的眼中是固定的。

添加 2

根据AnT的说法,边界设置似乎是硬连线的,它是由内存访问硬件硬连线的。就这一点而言,CPU 是无辜的。

4

4 回答 4

29

在这种情况下,“can”(在“...CPU can access...”中)的含义取决于硬件平台。

在 x86 平台上,CPU 指令可以访问在绝对任何边界上对齐的数据,而不仅仅是在“字边界”上。未对齐的访问可能比对齐的访问效率低,但其原因与 CPU 完全无关。它与底层低级内存访问硬件的工作方式有关。在这种情况下,与内存相关的硬件很可能必须对实际内存进行两次访问,但这是 CPU 指令不知道也不需要知道的事情。就 CPU 而言,它可以访问任何边界上的任何数据。其余的对 CPU 指令是透明的。

在 Sun SPARC 等硬件平台上,CPU无法访问未对齐的数据(简单地说,如果您尝试访问,您的程序将崩溃),这意味着如果由于某种原因您需要执行这种未对齐的访问,您必须实现它手动且显式地:将其拆分为两个(或更多)CPU 指令,从而显式执行两个(或更多)内存访问。

至于为什么会这样……嗯,这就是现代计算机内存硬件的工作原理。数据必须对齐。如果未对齐,则访问效率较低或根本不起作用。

现代记忆的一个非常简化的模型将是一个单元格(行和列),每个单元格存储一个数据字。可编程机械臂可以将单词放入特定单元格并从特定单元格中检索单词。一次一个。如果您的数据分布在多个单元格中,您别无选择,只能使用该机械臂进行多次连续旅行。在某些硬件平台上,组织这些连续行程的任务对 CPU 是隐藏的(这意味着手臂本身知道如何从多个片段中组装必要的数据),在其他平台上,它对 CPU 是可见的(意味着它是CPU 负责组织手臂的这些连续行程)。

于 2010-09-07T05:15:00.460 回答
8

如果您可以对地址做出某些假设(例如“底n部位为零),它可以节省寻址逻辑中的硅。一些 CPU(x86 及其类似工作)将放置逻辑以将未对齐的数据转换为多个提取,隐藏一些程序员对性能的不利影响。这个世界之外的大多数 CPU 都会引发硬件错误,毫不含糊地解释他们不喜欢这样。

您将听到的关于“效率”的所有论点都是胡说八道,或者更准确地说是在乞求问题。真正的原因很简单,如果可以减少操作的地址位数,它可以节省处理器内核中的硅片。任何由未对齐访问(如 x86 世界)引起的低效率都是硬件设计决策的结果,而不是一般寻址所固有的。

话虽如此,对于大多数用例来说,硬件设计决策是有意义的。如果您以两个字节的字访问数据,最常见的用例是您访问offset, then offset+2, thenoffset+4等等。在访问两字节字时能够逐字节递增地址通常不是您想要做的(当然在 99.44% 中)。因此,要求地址偏移量在字边界上对齐并没有什么坏处(当您设计数据结构时,这是一种轻微的一次性不便),但它确实可以节省您的芯片。

顺便说一句,我曾经在 Interdata Model 70 上工作过——一台 16 位的小型计算机。它要求所有内存访问都是 16 位对齐的。当我按照当时的标准处理它时,它的内存量也非常小。(即使在当时它也是一个遗物。)字对齐用于将内存容量翻倍,因为绕线的 CPU 很容易被黑客入侵。添加了新的地址解码逻辑,该逻辑在地址的低位中取 1(以前是一个对齐错误),并使用它来切换到第二组内存。在没有对齐逻辑的情况下尝试!:)

于 2010-09-07T05:21:55.253 回答
3

因为它更有效率。

在您的示例中,CPU 必须进行两次读取:它必须读取前半部分,然后分别读取后半部分,然后将它们重新组合在一起以进行计算。如果数据正确对齐,这比一次性读取要复杂得多,而且速度要慢得多。

一些处理器,如 x86,可以容忍未对齐的数据访问(因此您仍然需要所有 32 位) - 其他像安腾这样的处理器绝对无法处理未对齐的数据访问,并且会非常抱怨。

于 2010-09-07T05:11:03.917 回答
3

字对齐不仅是 CPU 的特色

在硬件层面上,大多数 RAM 模块具有给定的字大小,相对于每个读/写周期可以访问的位数。

在我必须与嵌入式设备连接的模块上,寻址是通过三个参数实现的: 模块分为四个组,可以在 RW 操作之前进行选择。这些银行中的每一个本质上都是一个 32 位字的大表,可以通过行和列索引来寻址。

在这个设计中,每个单元只能访问,所以每个读操作返回 4 个字节,每个写操作都需要 4 个字节。

连接到该 RAM 芯片的内存控制器可以通过两种方式设计:或者允许使用多个周期来不受限制地访问内存芯片,以将未对齐的数据拆分/合并到/来自多个单元(具有附加逻辑),或者对如何进行一些限制可以通过降低复杂性来访问内存。

As complexity can impede maintainability and performance, most designers chose the latter [citation needed]

于 2010-09-07T06:24:40.957 回答