我听到很多数据应该在内存中正确对齐,以提高访问效率。 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字节字边界,则地址线只需要30bit,而不是32bit宽度。因为CPU的眼中最后2位始终为0。
更重要的是,如果我们承认CPU必须读取字边界,为什么 边界不能从我想要读取的位置开始?在CPU的眼中,似乎边界固定。
根据 AndreyT ,似乎边界设置是硬连线的,并且它是由内存访问硬件硬连线的。就这一点而言,CPU是无辜的。
非常感谢......
答案 0 :(得分:24)
在这种情况下,“can”(在“...... CPU可以访问......”)中的含义取决于硬件平台。
在x86平台上,CPU指令可以访问在绝对任何边界上对齐的数据,而不仅仅是“字边界”。未对齐的访问可能不如对齐访问有效,但其原因与CPU完全无关。它与底层低级内存访问硬件的工作方式有关。在这种情况下,与存储器相关的硬件很可能必须对实际存储器进行两次访问,但这是CPU指令不知道并且不需要知道的事情。就CPU而言,它可以访问任何边界上的任何数据。其余部分透明地实现到CPU指令。
在Sun SPARC等硬件平台上,CPU 无法访问未对齐的数据(简单来说,如果您尝试,程序将崩溃),这意味着如果由于某种原因您需要执行此类操作对于未对齐的访问,您必须手动并显式地实现它:将其拆分为两个(或更多)CPU指令,从而显式执行两个(或更多)内存访问。
至于为何如此......好吧,这就是现代计算机内存硬件的工作原理。数据必须对齐。如果未对齐,则访问效率较低或根本不起作用。
现代记忆的一个非常简化的模型是细胞网格(行和列),每个细胞存储一个数据字。可编程机器人手臂可以将单词放入特定单元格并从特定单元格中检索单词。一次一个。如果您的数据分布在多个单元格中,则除了使用该机械臂连续几次跳闸之外别无选择。在某些硬件平台上,组织这些连续行程的任务对CPU是隐藏的(意味着手臂本身知道如何从多个部件组装必要的数据),在其他平台上它对CPU是可见的(意味着它是负责组织这些连续行程的CPU。)
答案 1 :(得分:4)
如果您可以对地址做出某些假设(例如“底部n
位为零),它会将硅保存在寻址逻辑中。某些CPU(x86及其工作相似)将使逻辑到位将数据错位到多个提取中,隐藏了程序员的一些令人讨厌的性能命中。大多数CPU在这个世界之外会引发硬件错误,并且毫不含糊地解释他们不喜欢这个。
你要听到的关于“效率”的所有论据都是僵尸,或者更准确地说是乞求这个问题。真正的原因很简单,如果可以减少操作的地址位数,它可以节省处理器内核中的硅。由于未对齐访问而产生的任何低效率(如在x86世界中)都是硬件设计决策的结果,而不是通常的寻址所固有的。
现在可以说,对于大多数用例而言,硬件设计决策是有道理的。如果您使用双字节字访问数据,则大多数常见用例都可以访问offset
,然后offset+2
,然后offset+4
,依此类推。能够在访问双字节字时按字节递增地址通常(当然在99.44%中)并不是您想要做的事情。因此,要求地址偏移在字边界上对齐并没有什么坏处(在设计数据结构时这是一个温和的,一次性的不便),但确实可以节省你的芯片。
作为历史的一部分,我曾在Interdata Model 70(一台16位小型机)上工作过一次。它要求所有内存访问都是16位对齐的。当我按照当时的标准进行工作时,它的内存也非常少。 (甚至当时它也是一个遗物。)字对齐用于使内存容量加倍,因为绕线的CPU很容易被黑客入侵。添加了新的地址解码逻辑,在地址的低位(先前是制作中的对齐错误)中取1并使用它切换到第二存储区。尝试没有对齐逻辑! :)
答案 2 :(得分:3)
因为效率更高。
在您的示例中,CPU必须执行两次读取:它必须在前半部分读取,然后分别在后半部分读取,然后将它们重新组合在一起进行计算。如果数据正确对齐,这比一次读取要复杂得多,速度慢。
某些处理器(如x86)可以容忍未对齐的数据访问(因此您仍然需要所有32位) - 其他像Itanium绝对无法处理未对齐的数据访问,并且会非常抱怨。
答案 3 :(得分:2)
Word对齐不仅仅是CPU的特色
在硬件级别上,大多数RAM模块具有相对于每个读/写周期可访问的位数的给定字大小。
在我必须在嵌入式设备上接口的模块上,通过三个参数实现寻址:模块组织在四个库中,可以在RW操作之前选择。每个银行本质上都是一个32位的大表,可以通过行和列索引来解决。
在本设计中,只能访问每个单元,因此每个读操作返回4个字节,每个写操作需要4个字节。
连接到此RAM芯片的内存控制器可以通过两种方式设计:允许使用几个周期无限制地访问内存芯片,以将未对齐数据拆分/合并到多个单元(带有附加逻辑),或者强加一些限制了如何通过降低复杂度来获取内存。
由于复杂性会影响可维护性和性能,大多数设计师选择后者[需要引用]