Правила выравнивания - PullRequest
       25

Правила выравнивания

2 голосов
/ 07 декабря 2010

У меня проблемы с домашней работой, и мне было интересно, сможет ли кто-нибудь указать мне правильное направление.

Предположим, мы компилируем для машины с 1-байтовыми символами, 2-байтовыми шорты, 4-байтовые целые и 8-байтовые и с правилами выравнивания, которые запрашивать адрес каждого примитива элемент данных, чтобы быть четным кратным размер элемента. Пусть дальше что компилятору не разрешено изменить порядок полей. Сколько места будет потребляется следующим массивом?

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

Теперь я понимаю проблему, по большей части, но вещь, которая действительно бросает меня в цикл - это «правила выравнивания, которые требуют адреса всех примитивных данных. элемент должен быть даже кратным размеру элемента ". Моя книга не очень подходит для описания правил выравнивания и, если честно, я даже не уверен в том, что такое кратное число. Любая помощь будет принята с благодарностью.

Кроме того, я считаю, что ответ - 240 байтов, мне просто нужна помощь, чтобы туда добраться.

Ответы [ 3 ]

3 голосов
/ 07 декабря 2010

Давайте разберемся с этим:

"правила выравнивания", которые "требуют, чтобы адрес каждого примитивного элемента данных был кратным размеру элемента".Не очень интересно, что мы говорим о правилах выравнивания;мы уже знали, что.

«требуют, чтобы адрес» каждого «простого элемента данных» был «четным кратным размера элемента».Теперь мы куда-то добираемся.У нас есть требование и область действия:

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

Итак, каждый раз, когда мы позиционируем элемент, мы должны налагать требование.

Давайте попробуем поместить элемент в память.Первое, что мы разместим, это short, помеченный s.Поскольку short занимает 2 байта памяти, и мы должны сделать его адрес кратным этому размеру, адрес должен быть кратным 2. Давайте назовем этот адрес N.

Итак, s занимаетпространство от N до N + 2.( ПРИМЕЧАНИЕ : для всех этих диапазонов первая конечная точка включена, а последняя - нет. Это обычный способ описания диапазонов целых чисел в информатике; в большинстве случаев это, безусловно,самый полезный и наименее подверженный ошибкам способ сделать это. Поверьте мне.)

Мы продолжаем работу друг с другом.

c занимает один байт, от N + 2 до N + 3.

Мы находимся на N + 3, но мы не можем начать там t, потому что N + 3 нечетно (поскольку N четно).Поэтому мы должны пропустить байт.Таким образом, t варьируется от N + 4 до N + 6.

Продолжая эту логику, мы получим d от N + 6 до N + 7;r от N + 8 до N + 16;i от N + 16 до N + 20.( ПРИМЕЧАНИЕ , что это работает, только если мы ограничим N кратным 8, или r будет не выровнено. Это нормально; когда мы выделяем память для массива, мы можем выровнять началокак бы мы этого ни хотели - мы просто должны быть последовательными в отношении последовательности данных после этой точки.)

Поэтому нам нужно не менее 20 байтов для этой структуры.(Это одно из преимуществ полуоткрытых диапазонов: разница между конечными точками равна размеру. Если бы мы включили или исключили обе конечные точки из диапазона, мы должны были бы сделать поправку +1 или -1.)

Теперь предположим, что мы пытаемся разложить массив как десять последовательных кусков по 20 байтов.Будет ли это работать?Нет;скажем, что элемент 0 находится по адресу 256 (кратно 8).Теперь r в элементе 1 будет не выровнен, потому что он начнется с 256 + 20 + 8, который не делится на 8. Это не разрешено.

Так что же нам теперь делать?Мы не можем просто вставить дополнительные 4 байта перед r в элементе 1, потому что каждый элемент массива должен иметь одинаковую разметку (не говоря уже о размере).Но есть простое решение: мы вставляем 4 байта дополнительного дополнения в end из каждого элемента.Теперь, пока массив начинается с кратного 8, каждый элемент также будет начинаться с кратного 8 (что, в свою очередь, сохраняет r выровненным), потому что размер теперь кратен 8.

Мы заключаем, что нам нужно 24 байта для структуры, и, таким образом, 24 * 10 = 240 байтов для массива.

2 голосов
/ 07 декабря 2010

Фраза "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 выровнен правильно.

0 голосов
/ 07 декабря 2010

Я не согласен - я читаю "an even multiple of the element’s size" как «2-байтовые шорты должны иметь четные адреса», или «4-байтовые числа должны быть выровнены по 4 байта». Таким образом, int по адресу 0x101 to 0x103 является ошибкой шины, но 0x100 и 0x104 являются правильными

...