OberonCore
https://forum.oberoncore.ru/

Не работает упаковка
https://forum.oberoncore.ru/viewtopic.php?f=2&t=5384
Страница 1 из 2

Автор:  Иван Денисов [ Четверг, 09 Апрель, 2015 15:49 ]
Заголовок сообщения:  Не работает упаковка

Валерий Шипков обнаружил интересную особенность компилятора, не работает упаковка обычных записей.

Вот простейшая демонстрация находки:
Код:
MODULE TestRecPack;
       
       IMPORT SYSTEM, Log;

       TYPE
               NotAligned =  RECORD [noalign]
                       b1: BYTE;
                       i1: INTEGER;
                       b2: BYTE;
                       i2: INTEGER;
                       b3: BYTE;
                       i3: INTEGER;
                       b4: BYTE;
                       i4: INTEGER;
               END;

               Aligned =  RECORD
                       b1: BYTE;
                       i1: INTEGER;
                       b2: BYTE;
                       i2: INTEGER;
                       b3: BYTE;
                       i3: INTEGER;
                       b4: BYTE;
                       i4: INTEGER;
               END;
               
       PROCEDURE Start*;
               VAR
       BEGIN
               Log.String("Not aligned: "); Log.Int(SIZE(NotAligned)); Log.Ln;
               Log.String("Aligned: ");Log.Int(SIZE(Aligned)); Log.Ln;
       END Start;
       
END TestRecPack.

^Q  TestRecPack.Start


Результат несколько неожиданный...

Код:
Not aligned:  20
Aligned:  32


Как вы думаете это баг или фича?

Автор:  Иван Денисов [ Четверг, 09 Апрель, 2015 16:02 ]
Заголовок сообщения:  Re: Не работает упаковка

При этом нельзя сказать, что выравнивание не работает.

Вот такой тест:
Код:
MODULE TestRecPack;
       
       IMPORT SYSTEM, Log;

       TYPE
               Aligned1 =  RECORD
                       b1: BYTE;
                       i1: INTEGER;
                       b2: BYTE;
                       i2: INTEGER;
                       b3: BYTE;
                       i3: INTEGER;
                       b4: BYTE;
                       i4: INTEGER;
               END;

               Aligned2 =  RECORD
                       b1, b2, b3, b4: BYTE;
                       i1, i2, i3, i4: INTEGER;
               END;
               
       PROCEDURE Start*;
               VAR
       BEGIN
               Log.String("Rec1: "); Log.Int(SIZE(Aligned1)); Log.Ln;
               Log.String("Rec2: ");Log.Int(SIZE(Aligned2)); Log.Ln;
       END Start;
       
END TestRecPack.

^Q TestRecPack.Start


Выдает:
Код:
Rec1:  32
Rec2:  20


То есть размер структуры в памяти в этом случае зависит от порядка указания переменных. Это логично, если выравнивание работает, а упаковка нет.

Автор:  Alexander Shiryaev [ Пятница, 10 Апрель, 2015 00:39 ]
Заголовок сообщения:  Re: Не работает упаковка

Иван Денисов писал(а):
Результат несколько неожиданный...

Почему неожиданный?

Автор:  Иван Денисов [ Пятница, 10 Апрель, 2015 05:40 ]
Заголовок сообщения:  Re: Не работает упаковка

Alexander Shiryaev писал(а):
Иван Денисов писал(а):
Результат несколько неожиданный...

Почему неожиданный?

Получилось, что структура без выравнивания упаковалась и стала меньше, чем структура которая вроде как, должна выровняться. Вопрос, она должна упаковаться? Почему упаковка отключена в стандартных записях с тегами?

Автор:  Иван Денисов [ Пятница, 10 Апрель, 2015 05:44 ]
Заголовок сообщения:  Re: Не работает упаковка

В книге алгоритмы и структуры данных упоминается некий PACKED. Но как я понимаю, он там только как предложение. То есть пока не реализован.

Но почему тогда [noalign] записи упаковываются?

Вложение:
packed.png
packed.png [ 99.45 КБ | Просмотров: 21180 ]

Автор:  Alexander Shiryaev [ Пятница, 10 Апрель, 2015 10:38 ]
Заголовок сообщения:  Re: Не работает упаковка

Иван Денисов писал(а):
Alexander Shiryaev писал(а):
Иван Денисов писал(а):
Результат несколько неожиданный...

Почему неожиданный?

Получилось, что структура без выравнивания упаковалась и стала меньше, чем структура которая вроде как, должна выровняться. Вопрос, она должна упаковаться? Почему упаковка отключена в стандартных записях с тегами?

Выравнивания нет (noalign, "not aligned", то есть упакована), поэтому и меньше.

not aligned ("packed"):
Код:
NotAligned =  RECORD [noalign]
    b1: BYTE;
    i1: INTEGER;
    b2: BYTE;
    i2: INTEGER;
    b3: BYTE;
    i3: INTEGER;
    b4: BYTE;
    i4: INTEGER;
END;

1 + 4 + 1 + 4 + 1 + 4 + 1 + 4 = 20

aligned ("not packed"):
Код:
Aligned1 =  RECORD
    b1: BYTE;
    i1: INTEGER;
    b2: BYTE;
    i2: INTEGER;
    b3: BYTE;
    i3: INTEGER;
    b4: BYTE;
    i4: INTEGER;
END;

4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 = 32
Код:
Aligned2 =  RECORD
    b1, b2, b3, b4: BYTE;
    i1, i2, i3, i4: INTEGER;
END;

4 + 4 * 4 = 20

Автор:  Иван Денисов [ Пятница, 10 Апрель, 2015 15:35 ]
Заголовок сообщения:  Re: Не работает упаковка

А как заставить запись одновременно и паковаться и чтобы сборщик мусора с ней работал?
Ведь noalign это подвид untagged, поэтому такие записи не будет сборщик мусора убирать.

Автор:  Alexander Shiryaev [ Пятница, 10 Апрель, 2015 15:51 ]
Заголовок сообщения:  Re: Не работает упаковка

Иван Денисов писал(а):
А как заставить запись одновременно и паковаться и чтобы сборщик мусора с ней работал?
Ведь noalign это подвид untagged, поэтому такие записи не будет сборщик мусора убирать.

Так нельзя даже динамически память выделить под неё (NEW работать не будет), поэтому и собирать нечего.

Зачем вообще тебе нужны упакованные (невыровненные) записи? См. "Выравнивание данных"

Если память сэкономить -- меняй порядок полей в записи.

Автор:  Иван Денисов [ Суббота, 11 Апрель, 2015 06:39 ]
Заголовок сообщения:  Re: Не работает упаковка

Спасибо, Александр. Кажется я понял, почему notaligned 20 байт, это не потому что она упакована, а потому что она не выровнена. Она не выровнена, но и не упакована. packed это не антоним к aligned

Запись может быть выровнена, но не упакована. Получается, что автоматической упаковки как таковой нет в ББ в принципе? Или в ББ упаковка такая, что по условию не нарушает порядок переменных? Надо самому рассчитывать порядок объявления переменных и соответствие их групп машинному слову, чтобы получить оптимальную производительность при выравнивании?

Автор:  Роман М. [ Суббота, 11 Апрель, 2015 13:20 ]
Заголовок сообщения:  Re: Не работает упаковка

Иван Денисов писал(а):
Спасибо, Александр. Кажется я понял, почему notaligned 20 байт, это не потому что она упакована, а потому что она не выровнена. Она не выровнена, но и не упакована. packed это не антоним к aligned

Запись может быть выровнена, но не упакована. Получается, что автоматической упаковки как таковой нет в ББ в принципе? Или в ББ упаковка такая, что по условию не нарушает порядок переменных? Надо самому рассчитывать порядок объявления переменных и соответствие их групп машинному слову, чтобы получить оптимальную производительность при выравнивании?

Для производительности "упаковывать" нужно по машинному слову, а для экономии места в памяти - в точности как описан тип в записи без выравнивания под размер машинного слова. Бывает выравнивание и на меньшие размеры ячеек, как правило, кратные 2. Подробнее в Википедии: Выравнивание данных

Модификатор PACKED имеет тот же смысл, что и noalign - инструкция компилятору не выравнивать по ячейкам машинного слова.
http://www.delphibasics.co.uk/RTL.asp?Name=Packed (Delphi)
Если я правильно понимаю, с выравниванием под машинное слово компилятор сможет лучше оптимизировать код под низлежащую архитектуру для более быстрого доступа к ячейкам структуры записи.

Автор:  Info21 [ Суббота, 11 Апрель, 2015 14:12 ]
Заголовок сообщения:  Re: Не работает упаковка

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

Автор:  Valery Solovey [ Суббота, 11 Апрель, 2015 14:32 ]
Заголовок сообщения:  Re: Не работает упаковка

Иван Денисов писал(а):
Запись может быть выровнена, но не упакована. Получается, что автоматической упаковки как таковой нет в ББ в принципе?
Возможно, это из-за расширения типа. Если у нас в одном модуле есть запись, а в другом мы её расширяем, то упаковка сделает смещение одной и той же переменной в этих двух типах разным. Этого, конечно, можно избежать, используя частичную упаковку, когда ей подвергаются только переменные текущего типа, но не базового. Однако, для этого, думаю, нужна информация в символьном файле.

Автор:  Alexander Shiryaev [ Суббота, 11 Апрель, 2015 14:40 ]
Заголовок сообщения:  Re: Не работает упаковка

Иван Денисов писал(а):
В книге алгоритмы и структуры данных упоминается некий PACKED. Но как я понимаю, он там только как предложение. То есть пока не реализован.

Но почему тогда [noalign] записи упаковываются?

Вложение:
packed.png

В Delphi (7) packed record -- это и есть [noalign] в Component Pascal

Автор:  prospero78 [ Воскресенье, 12 Апрель, 2015 18:30 ]
Заголовок сообщения:  Re: Не работает упаковка

Что самое интересное -- поля записей без выравнивания не имеют проигрыша по времени по сравнению с записями, где поля выровнены через оптимальное описание.
А вот записи автоматически выравненные (32 байта против 20) будут иметь большее время обработки. Причём проигрышь будет меньше либо равен прямому отношению 32/20. Это связано с алгоритмом обработки и его объёмом (влияют модули ЦП, такие как двойной АЛУ (или на удвоенной частоте), механизм предсказания ветвлений, глубина конвейера и размер кеша.

Автор:  Alexander Shiryaev [ Воскресенье, 12 Апрель, 2015 23:10 ]
Заголовок сообщения:  Re: Не работает упаковка

На x86?

Автор:  prospero78 [ Понедельник, 13 Апрель, 2015 09:10 ]
Заголовок сообщения:  Re: Не работает упаковка

Alexander Shiryaev писал(а):
На x86?

Так точно.

Автор:  Иван Денисов [ Понедельник, 13 Апрель, 2015 10:10 ]
Заголовок сообщения:  Re: Не работает упаковка

Наивно полагал, что есть три альтернативы:
1. Просто запись последовательно размещенная.
2. Выровненная запись по словам.
3. Упакованная запись с оптимальным для выравнивания порядком переменных.
Теперь понимаю, что третье — это моя фантазия :)

В случае оптимизации кода, требуется следить, чтобы переменные шли кучками длиной с машинное слово. Видимо поэтому раздел с описанием особенностей размещения записей в оперативной памяти в самом начале книги "Алгоритмы и структуры данных" и дан. Достаточно важная информация, но получается, что дана не очень понятно.

Автор:  prospero78 [ Понедельник, 13 Апрель, 2015 13:58 ]
Заголовок сообщения:  Re: Не работает упаковка

Иван Денисов писал(а):
Достаточно важная информация, но получается, что дана не очень понятно.

Ты в курсе, Вань, сколько там непоняток (по крайней мере для меня). Соответствующий запрос в соответствующую ветку форума написал, ждём ответа по существу.
Вообще, зреет у меня мысль, надо написать свой учебник в формате wiki поверх creative common с принудительной регистрацией. Негде привязаться. Есть смысл по этому поводу где-то отдельную ветку поднять?

Автор:  Kemet [ Понедельник, 13 Апрель, 2015 15:19 ]
Заголовок сообщения:  Re: Не работает упаковка

Иван Денисов писал(а):
Наивно полагал, что есть три альтернативы:
1. Просто запись последовательно размещенная.
Это и есть упакованная запись.
Цитата:
2. Выровненная запись по словам.
Не обязательно по словам, а на архитектурно зависимое значение.

Автор:  prospero78 [ Понедельник, 13 Апрель, 2015 15:32 ]
Заголовок сообщения:  Re: Не работает упаковка

Kemet писал(а):
Иван Денисов писал(а):
Наивно полагал, что есть три альтернативы:
1. Просто запись последовательно размещенная.
Это и есть упакованная запись.
Цитата:
2. Выровненная запись по словам.
Не обязательно по словам, а на архитектурно зависимое значение.


ИМХО, возможно ошибаюсь, но

1. Последовательно размещённая запись # упакованная запись. Поле имеющее размер с машинное слово может запросто пересекать границы машинного слова, если поле не началось с начала машинного слова. Процессор будет вынужден подстраивать адреса под наиболее удобный вид представления.

2. Слово -- это и есть представление данных, обусловленное архитектурой. Т. е. слово для 8 бит -- 1 байт; 16 бит -- два байта; 32 бита -- 4 байта и т. д. Из-за этого существует путаница в обозначениях. В этом смысле, я недолюбливаю обозначения INTEGER и REAL -- почти никакой информации о диапазоне и размере.

Страница 1 из 2 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/