理解单词对齐

Posted

技术标签:

【中文标题】理解单词对齐【英文标题】:Understanding word alignment 【发布时间】:2009-10-18 07:38:04 【问题描述】:

我理解访问内存以使其对齐意味着什么,但我不明白为什么这是必要的。例如,为什么我可以从地址0x…1 访问单个字节,但我不能从同一地址访问半字(两个字节)。

我再次了解,如果您有一个地址 A 和一个大小为 s 的对象,则访问是对齐的,如果 A mod s = 0。但我就是不明白为什么这在硬件层面很重要。

【问题讨论】:

【参考方案1】:

硬件很复杂;这是一个简化的解释。

典型的现代计算机可能具有 32 位数据总线。这意味着 CPU 需要执行的任何获取操作都将获取特定内存地址的所有 32 位。由于数据总线无法获取小于 32 位的任何内容,因此地址总线上甚至不使用最低的两个地址位,因此就好像 RAM 被组织成一个 32 位 字的序列 而不是 8 位 字节

当 CPU 获取单个字节时,总线上的读取周期将获取 32 位,然后 CPU 将丢弃其中的 24 位,将剩余的 8 位加载到任何寄存器中。如果 CPU 想要获取 在 32 位边界上对齐的 32 位值,它有几个通用选择:

在总线上执行两个单独的读取周期以加载数据字的适当部分并重新组合它们 在通过丢弃地址的低两位确定的地址处读取 32 位字 读取组合成 32 位字的一些意想不到的字节组合,可能不是您想要的 抛出异常

我使用过的各种 CPU 都采用了所有这四个路径。一般来说,为了获得最大的兼容性,将所有 n 位读取对​​齐到 n 位边界是最安全的。但是,如果您确定您的软件将在具有已知未对齐读取行为的特定 CPU 系列上运行,您当然可以走捷径。即使可以进行非对齐读取(例如在 x86 系列 CPU 上),它们也会变慢。

【讨论】:

地址总线上甚至没有使用最低的两个地址位 如果是这样,那么如何仅用 30 位寻址 32 位地址?如果我错了,请纠正我。 是的,那部分需要澄清。他两次提到最低两位。在第二种解决方案中,听起来他可以读取一次而不是两次读取,这也没有意义,因为我们说它没有对齐。 不是必须设置为 0 的最低有效 5 位吗 谁能解释一下为什么这里不使用最低 2 位?【参考方案2】:

计算机总是读入一些对齐的固定大小的块。

因此,如果您不对齐内存中的数据,您可能需要读取不止一次。

示例

字长为 8 个字节 你的结构也是 8 个字节 如果对齐,则必须读取一大块 如果不对齐,则必须读取两个块

所以,基本上是为了加快速度。

【讨论】:

【参考方案3】:

all 对齐规则的原因是缓存行的宽度不同(Core2 架构的指令缓存确实有 16 字节行,而数据缓存确实有 64 字节的行L1 和 L2 的 128 字节行)。

因此,如果您要存储/加载跨越 Cahce-Line 边界的数据,则需要加载和存储两条 Cache-line,这会影响性能。 因此,您不要因为性能受到影响而这样做,就这么简单。

【讨论】:

您能否详细说明您的答案?听起来很有趣。现代处理器很少直接寻址内存。他们实际从中获取数据的是缓存。所以字对齐应该只与缓存有关吗?非常感谢【参考方案4】:

尝试读取串行端口。数据为 8 位宽。 优秀的硬件设计师确保它位于单词的最低有效字节上。

如果你有一个 C 结构的元素不是字对齐的(从向后兼容性或内存保护说) 那么结构中任何字节的地址都不是字对齐的。

【讨论】:

以上是关于理解单词对齐的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode 68.文本左右对齐

如何使用javascript将单词向右对齐

Leetcode No.68 文本左右对齐(模拟)

68. Text Justification一行单词 两端对齐

coreldraw在对英文进行排版的时候,为啥会出现无法对齐?

LeetCode Text Justification