【问题标题】:Alignment Rules对齐规则
【发布时间】:2010-12-07 07:31:09
【问题描述】:

我在作业问题上遇到了一些麻烦,我想知道是否有人能指出我正确的方向。

假设我们正在为一台机器编译 1字节字符,2字节 短裤、4 字节整数和 8 字节 实数,并使用对齐规则 需要每个原语的地址 数据元素为偶数倍 元素的大小。进一步假设 不允许编译器 重新排序字段。会有多少空间 被下面的数组消耗了吗?

A : array [0..9] of record
    s : short;
    c : char;
    t : short;
    d : char;
    r : real;
    i : integer;
end;

现在我在很大程度上理解了这个问题,但真正让我陷入循环的是“需要每个原始数据地址的对齐规则” 元素是元素大小的偶数倍”。我的书在对齐规则方面的描述不是很好,老实说,我什至不肯定偶数是什么。任何帮助将不胜感激。

另外,我相信答案是 240 字节,我只是需要一些帮助才能到达那里。

【问题讨论】:

    标签: memory location alignment rules


    【解决方案1】:

    让我们分解一下:

    “对齐规则”,“要求每个原始数据元素的地址是元素大小的偶数倍”。我们谈论对齐规则并不是很有趣。我们已经知道了。

    “要求每个原始数据元素”的地址是“元素大小的偶数倍”。现在我们正在取得进展。我们有一个要求和一个范围:

    Requirement: The address is an even multiple of the element's size.
    Scope: Every primitive data element.
    

    所以,每次我们定位一个元素时,我们都必须提出这个要求。

    让我们尝试在内存中定位一个元素。我们将定位的第一件事是标记为s 的short。由于 short 占用 2 个字节的内存,并且我们必须使其地址成为该大小的倍数,因此该地址必须是 2 的倍数。我们称该地址为 N。

    所以,s 占用了从N 到N + 2 的空间。 (注意:对于所有这些范围,第一个端点都包括在内,但最后一个端点不包括在内。这是计算机科学中描述整数范围的正常方式;在大多数情况下,到目前为止最有用且最不容易出错的方法。相信我。)

    我们继续彼此领域。

    c占用一个字节,从N + 2到N + 3。

    我们在N + 3,但我们不能从那里开始t,因为N + 3 是奇数(因为N 是偶数)。所以我们必须跳过一个字节。因此t 的范围从N + 4 到N + 6。

    继续这种逻辑,我们最终得到从N + 6到N + 7的d; r 从 N + 8 到 N + 16; i 从 N + 16 到 N + 20。 (注意,这仅在我们将 N 限制为 8 的倍数时才有效,否则 r 将不对齐。这没关系;当我们为数组分配内存时,我们可以对齐开始不管我们想要什么——我们只需要在那之后的数据序列上保持一致。)

    所以我们需要至少 20 个字节用于这个结构。 (这是半开范围的优点之一:端点之间的差异等于大小。如果我们在范围中包含或排除两个端点,我们必须进行 +1 或 -1 校正。)

    现在假设我们尝试将数组布局为十个连续的 20 字节块。这行得通吗?不;假设元素 0 位于地址 256(8 的倍数)。现在元素 1 中的 r 将不对齐,因为它将从 256 + 20 + 8 开始,不能被 8 整除。这是不允许的。

    那么我们现在该怎么办?我们不能只在元素 1 的 r 之前插入额外的 4 个字节,因为数组的每个元素都必须具有相同的布局(更不用说大小)。但是有一个简单的解决方案:我们在 each 元素的 end 处插入 4 个字节的额外填充。现在,只要数组从 8 的倍数开始,每个元素也将以 8 的倍数开始(这反过来又保持r 对齐),因为现在大小是 8 的倍数。

    我们得出结论,结构需要 24 个字节,因此数组需要 24 * 10 = 240 个字节。

    【讨论】:

      【解决方案2】:

      例如,短语"an even multiple of the element’s size" 可能表示 2 字节短必须在 4 字节边界上对齐。

      这对我来说似乎有点浪费,但既然是家庭作业,那当然是可能的。

      使用这些规则,您将拥有(对于大小为 2 的数组):

      Offset  Variable  Size  Range
      ------  --------  ----  -----
           0     s         2    0-1
           4     c         1    2-2
           8     t         2    4-5
          12     d         1    6-6
          16     r         8  16-23
          24     i         4  24-27
          28     *         4  28-31
      
          32     s         2  32-33
          34     c         1  34-34
          36     t         2  36-37
          38     d         1  38-38
          48     r         8  48-55
          56     i         4  56-59
          60     *         4  60-63
      

      您有填充的原因是为了使每个数组元素达到 16 的倍数,以便每个中的 r 变量可以对齐到 16 个字节。

      所以在这种情况下,十个数组元素将占用 320 个字节。


      它也可能意味着“整数”中的“偶数”而不是“二的倍数”(因为它与现实相符,所以可能性更大)。

      这将使数组:

      Offset  Variable  Size  Range
      ------  --------  ----  -----
           0     s         2    0-1
           4     c         1    2-2
           8     t         2    4-5
          12     d         1    6-6
          16     r         8   8-15
          24     i         4  16-19
          28     *         4  20-23
      
          32     s         2  24-25
          34     c         1  26-26
          36     t         2  28-29
          38     d         1  30-30
          48     r         8  32-39
          56     i         4  40-43
          60     *         4  44-47
      

      在这种情况下,每个元素有 24 个字节,总共 240 个字节。同样,您需要填充以确保 r 正确对齐。

      【讨论】:

        【解决方案3】:

        我不同意 - 我将 "an even multiple of the element’s size" 读为“2 字节短裤必须有偶数地址”,或者“4 字节整数必须是 4 字节对齐”。所以,地址 0x101 to 0x103 的 int 是总线错误,但 0x100 和 0x104 是正确的

        【讨论】:

        • 你的意思是评论 paxdiablo 的回答吗?
        【解决方案4】:

        希望这在一定程度上可以解决问题:(准确地说是 236(232+4))

        import pprint
        l=[2,1,2,1,8,4]
        count=0
        i=0
        d={}
        while(count<10):
            for ele in l:
                while True:
                    if(i%ele==0):
                        d[i]=ele
                        i=i+ele
                        break
                    i=i+1
            count+=1
        pprint.pprint(d)  
        

        输出:

        {0: 2,
         2: 1,
         4: 2,
         6: 1,
         8: 8,
         16: 4,
         20: 2,
         22: 1,
         24: 2,
         26: 1,
         32: 8,
         40: 4,
         44: 2,
         46: 1,
         48: 2,
         50: 1,
         56: 8,
         64: 4,
         68: 2,
         70: 1,
         72: 2,
         74: 1,
         80: 8,
         88: 4,
         92: 2,
         94: 1,
         96: 2,
         98: 1,
         104: 8,
         112: 4,
         116: 2,
         118: 1,
         120: 2,
         122: 1,
         128: 8,
         136: 4,
         140: 2,
         142: 1,
         144: 2,
         146: 1,
         152: 8,
         160: 4,
         164: 2,
         166: 1,
         168: 2,
         170: 1,
         176: 8,
         184: 4,
         188: 2,
         190: 1,
         192: 2,
         194: 1,
         200: 8,
         208: 4,
         212: 2,
         214: 1,
         216: 2,
         218: 1,
         224: 8,
         232: 4}
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-02-01
          • 2013-06-26
          • 2017-12-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多