为什么CPU在字边界上访问内存?

我听到很多数据应该在内存中正确对齐,以提高访问效率。 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

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

非常感谢…

在这种情况下,“can”(在“…… CPU可以访问……”)中的含义取决于硬件平台。

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

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

至于为何如此……好吧,这就是现代计算机内存硬件的工作原理。 数据必须对齐。 如果它没有对齐,则访问效率较低或根本不起作用。

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

因为它更有效率。

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

某些处理器,如x86,可以容忍未对齐的数据访问(因此您仍然需要所有32位) – 其他像Itanium绝对无法处理未对齐的数据访问,并会抱怨相当惊人。

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

你将要听到的关于“效率”的所有论据都是僵尸,或者更准确地说是乞求这个问题。 真正的原因很简单,如果可以减少操作的地址位数,它可以节省处理器内核中的硅。 由于未对齐访问而产生的任何低效率(如在x86世界中)都是硬件设计决策的结果,而不是通常的寻址所固有的。

现在可以说,对于大多数用例而言,硬件设计决策是有意义的。 如果您以双字节字访问数据,则大多数常见用例都可以访问offset ,然后offset+2 ,然后offset+4 ,依此类推。 能够在访问双字节字时按字节递增地址通常(当然在99.44%中)不是您想要做的事情。 因此,要求地址偏移在字边界上对齐(在设计数据结构时这是一个温和的,一次性的不便)并没有什么坏处,但它确实可以节省你的芯片。

作为历史的一部分,我曾在Interdata Model 70(一台16位小型机)上工作过一次。 它要求所有内存访问都是16位对齐的。 当我按照当时的标准进行工作时,它的内存也非常少。 (甚至当时它也是一个遗物。)字对齐用于使内存容量加倍,因为绕线的CPU很容易被黑客入侵。 添加了新的地址解码逻辑,在地址的低位(之前是对齐错误)中取1并使用它切换到第二组存储器。 尝试没有对齐逻辑! 🙂

字对齐不仅仅是CPU的特色

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

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

在这种设计中, 每个单元只能访问,因此每个读操作返回4个字节,每个写操作预期4个字节。

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

由于复杂性会影响可维护性和性能,大多数设计师选择后者[ 需要引证 ]