C 编译器使用的数据布局(对齐概念)

问题描述 投票:0回答:1

以下是红龙书的摘录。

示例 7.3。图 7.9 是 C 编译器使用的数据布局的简化,用于我们称为 Machine 1Machine 2 的两台机器。

机器 1机器 1的内存被组织成字节,每个字节由 8 位组成。即使每个字节都有一个地址,指令集也倾向于将

short
整数放置在地址为偶数的字节处,并将整数放置在可被
4
整除的地址处。编译器将短整数放置在偶数地址处,即使它必须在进程中跳过一个字节作为填充。因此,可以为一个字符分配由
32
位组成的四个字节,后跟一个短整数。

机器2每个字由64位组成,一个字的地址允许使用24位。一个字内的各个位有 64 种可能性,因此需要 6 个附加位来区分它们。按照设计,指向机器 2 上的字符的指针需要 30 位,其中 24 位用于查找单词,6 位用于确定单词在单词中的位置。 机器 2 指令集的强字定位导致编译器一次分配一个完整的字,即使更少的位就足以表示该类型的所有可能值;例如,只需要 8 位来表示一个字符。因此,在对齐情况下,图 7.9 显示每种类型有 64 位。在每个字中,每种基本类型的位都位于指定位置。由 128 位组成的两个字将被分配给一个字符,后跟一个短整数,该字符仅使用第一个字中的 8 个位,而短整数仅使用第二个字中的 24 个位。 □

我在

这里这里这里找到了对齐的概念。我从他们那里得到的理解是:

在字可寻址CPU(大小大于一个字节)中,数据对象中引入了某些填充,以便CPU能够以最少的内存周期有效地从内存中检索数据。

现在这里的

机器1实际上是一个字节地址1。 Machine 1 规范中的条件可能比字大小为 4 字节的简单字可寻址机器更困难。在这样的64位机器中,我们需要确保我们的数据项只是字对齐,不再有困难。但是如何在像 Machine 1(如上表所示)这样的系统中找到对齐方式,在这些系统中,字对齐的简单概念不起作用,因为它是字节可寻址的并且具有更困难的规范。

此外,我发现很奇怪的是,在

double

 行中,类型的大小大于对齐字段中给出的大小。不应该
alignment(in bits) ≥ size (in bits)
吗?因为对齐是指实际为数据对象分配的内存(?)。

“每个字由 64 位组成,一个字的地址允许使用 24 位。一个字内的各个位有 64 种可能性,因此需要 6 个附加位来区分它们。根据设计,一个指针机器 2 上的字符需要 30 位 — 24 位用于查找单词,6 位用于确定字符在单词中的位置。" -

此外,关于基于对齐的指针概念的陈述应该如何可视化(2^6 = 64,很好,但这6位与对齐概念有何关联)?

c compiler-construction local memory-alignment runtime-environment
1个回答
2
投票
首先,机器 1 一点也不特殊——它就像 x86-32 或 32 位 ARM。

此外,我发现很奇怪的是,在 double 行中,类型的大小大于对齐字段中给出的大小。对齐(以位为单位)不应该≥大小(以位为单位)吗?因为对齐是指实际为数据对象分配的内存(?)。

不,这不是真的。对齐意味着对象中

最低可寻址字节的地址必须能被给定的字节数整除。

此外,对于

C,在arrays中,sizeof (ElementType)

也确实需要
大于或等于每个成员的对齐方式并且sizeof (ElementType)
可以被对齐整除,因此脚注A。因此在后一台计算机上:

struct { char a, b; }
可能有

16的大小,因为字符位于不同的可寻址单词中,而

struct { char a[2]; }
可以压缩成8个字节。


关于基于对齐的指针概念的陈述应该如何可视化(2^6 = 64,很好,但这 6 位与对齐概念有何关联)

对于字符指针来说,这6位是假的。需要 3 位来选择

8-byte 字中的 8 字节之一,因此这是书中的一个错误。普通字节将仅选择 24 位的字,字符(字节)指针将选择 24 位的字,以及字内 3 位的 8 位字节之一。

© www.soinside.com 2019 - 2024. All rights reserved.