![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
packed [D6]
SergP © (2006-02-04 23:56:00)Есть небольшой вопрос:
Если я использую какую-нить структуру, размер элементов которого кратен 4 байтам, будет ли разница в том применяю ли я в описании этого типа packed или не применяю?
И всегда ли?
SergP (2006-02-06 08:48:00) [1]
> Defunct © (06.02.06 02:39) [23]
> > Размер записи при выравнивании на 4 будет равен 7
>
> будет равен 8.
> проверьте сами sizeof( mrec ).
проверил. Кроме этого провери еще 2 записи:
Размер этой записи 6 байт:
type Mrec1=record
a1:word;
a2:word;
a3:word;
end;
А этой 8 байт:
type Mrec2=record
a1:cardinal;
a2:word;
end;
Хм. Действительно...
Оказывается компилятор умный очень.... Не ожидал... Недооценивал я его...
Defunct (2006-02-06 02:39:00) [2]> Размер записи при выравнивании на 4 будет равен 7
будет равен 8.
проверьте сами sizeof( mrec ).
SergP (2006-02-05 21:04:00) [3]
> begin...end © (05.02.06 20:44) [21]
Ну это понятно... Я просто хотел сказать что в приведенном мной примере
> SergP © (05.02.06 20:12) [20]
Несмотря на то что запись неупакована (т.е. элементы выравнены на 4), в массиве этих записей достоинство выравнивания записи должно потеряться (если учесть что размер записи - 7 (т.е. не кратное величине выравнивания).
Или лучше поясню схематически:
0 ------------------------------------------------------
.
. нулевой элемент массива (все элементы записи выравнены по 4)
.
4
.
.
. -----------------------------------------------------
8
.
. первый элемент массива (несмотря на то что в описании записи
. ее элементы выравнены, на самом деле запись будет сдвинута
12 относительно границы выравнивания
.
.---------------------------------------------------
.
16
Вот насчет этого скажите - правильно ли я понял?
begin...end (2006-02-05 20:44:00) [4]> SergP © (05.02.06 20:12) [20]
> Если размер элемента массива равен размеру записи (потому
> как массив всегда packed), то получается что выравнивание
> в записи нам ничего не дает?
Наличие/отсутствие packed в описании массива не влияет на размер его элемента.
Если тип записи (элемента массива) объявлен с указанием packed, то запись будет упакованной (т.е. её поля будут "прижаты" друг к другу) -- вне зависимости от того, будет ли она элементом упакованного или неупакованного массива, или какого-либо другого типа. А если тип записи объявлен без packed, то запись будет неупакованной -- и опять же, не имеет значения, в составе какого типа она находится.
А в описании массива указание packed теоретически должно влиять на то, будут ли сами элементы массива "прижаты" друг к другу. Но на практике, как уже было сказано, массивы всегда упакованы -- по крайней мере, пока.
SergP (2006-02-05 20:12:00) [5]
> Defunct © (05.02.06 08:39) [10]
> SergP © (05.02.06 08:33) [8]
>
> разницы нет ни для статических ни для динамических массивов,
> посколу они всегда и так packed.
А каков смысл выравнивания в записях, если иногда приходится использовать массивы записей?
Допустим
type Mrec=record
a1:word;
a2:byte;
a3:word;
a4:byte;
end;
Размер записи при выравнивании на 4 будет равен 7
А теперь создадим массив:
x:array of Mrec;
Если размер элемента массива равен размеру записи (потому как массив всегда packed), то получается что выравнивание в записи нам ничего не дает?
begin...end (2006-02-05 18:48:00) [6]> tesseract © (05.02.06 17:39) [18]
> Все структуры без packed кратны 4 байтам.
Ой.
tesseract (2006-02-05 17:39:00) [7]
> Если я использую какую-нить структуру, размер элементов
> которого кратен 4 байтам, будет ли разница в том применяю
> ли я в описании этого типа packed или не
Все структуры без packed кратны 4 байтам. Это делается для увеличения производительности intel процессоров.
> Пытался написать TForm1 = packed class... не прошло. Или
> что-то другое имелось в виду?
А зачем тебе? ведь можно объявить поле в классе и объявить его packed record.
Sapersky (2006-02-05 16:22:00) [8]А, ясно, у меня Delphi 5.
begin...end (2006-02-05 15:53:00) [9]> Sapersky (05.02.06 14:17) [15]
> Пытался написать TForm1 = packed class... не прошло.
А у меня прошло. Delphi 7.
P.S. И справка говорит, что packed можно писать в объявлении любого структурированного типа, а class именно таким типом и является.
Sapersky (2006-02-05 14:17:00) [10]2SergP:
Основной принцип дельфийского выравнивания: дополнительные байты вставляются в том случае, если какое-то поле записи попадает НА ГРАНИЦУ 4-х, для примера, байтов.
Т.е., например:
TRec = record
a,b : Byte;
c : Word;
end;
- общий размер 4 байта, т.к. все поля уложились в dword.
TRec = record
a,b,c : Byte;
d : Word;
end;
- общий размер 6 байт, т.к. половина d попала в 1-й dword, половина - во второй; d сдвигается на 1 байт.
TRec = record
i : Integer;
a,b,c : Byte;
d : Word;
end;
- общий размер... 12 байт, т.к. он округляется до размера кратного макс. размеру поля (точнее, максимальному выравниванию поля, которое в данном случае = размеру).
Такая вот хитрая логика :)
Если кто сомневается - это всё написано в help: Object Pascal Reference\Memory management\Record types.
Массивы, похоже, действительно всегда packed.
Кстати какой смысл ставить 8 на 32-разрядных процессорах?
Вроде бы это связано с особенностями доступа к памяти у P4.
Для MMX/SSE Дельфи слабо приспособлен, всё приходится выравнивать вручную - и размер записи, и начало обрабатываемой области памяти (GetMem выравнивает на 4).
Packed распространяется не только на record.
На class, например.
Пытался написать TForm1 = packed class... не прошло. Или что-то другое имелось в виду?
AFAIK, классы всегда выравниваются, т.е. не-packed.
begin...end (2006-02-05 09:39:00) [11]> Defunct © (05.02.06 09:14) [13]
Одно лишь отсутствие принципиальной разницы в организации полей не позволяет утверждать, что class -- частный случай record. Этак можно сказать, что set -- это частный случай array, и т.д.
В утверждении из [4] ясно указано, что речь идёт о record. Поэтому оно неверно.
Defunct (2006-02-05 09:14:00) [12]кому как.
принципиальной разницы в организации полей данных record/object/class, как для меня, нет.
begin...end (2006-02-05 08:46:00) [13]> Defunct © (05.02.06 08:42) [11]
> если можно так выразиться
Нельзя.
Defunct (2006-02-05 08:42:00) [14]begin...end © (05.02.06 08:34) [9]
ну да, но это, как и object, частный случай record . (если можно так выразиться)
Defunct (2006-02-05 08:39:00) [15]SergP © (05.02.06 08:33) [8]
разницы нет ни для статических ни для динамических массивов, посколу они всегда и так packed.
begin...end (2006-02-05 08:34:00) [16]> Defunct © (05.02.06 08:30) [7]
На class, например.
SergP (2006-02-05 08:33:00) [17]хм... Проверил... Вроде бы разницы array или packed array не заметил...(правда пробовал только на статических массивах)...
Хотя Delphi не ругается на packed перед array
Defunct (2006-02-05 08:30:00) [18]begin...end © (05.02.06 08:20) [5]
на что еще?
SergP (2006-02-05 08:21:00) [19]
> Defunct © (05.02.06 08:07) [4]
> packed не распространяется на array.
> packed распространяется только на record.
Вот цитата из Фаронова:
В целях совместимости со стандартным Pascal в Delphi разрешается перед описанием структурированного типа ставить зарезервированное слово packed ...
Автор не пишет что только перед record, а пишет что перед описанием структурированного типа, которым array также является.
Или это следует понимать по другому?
Вобщем в моем случае имеется большой массив записей, где не требуется быстродействие при работе с каждым элементом в отдельности, но требуется быстродействие при работе с блоком памяти, занимаемым всем массивом целиком, поэтому я подумал, что чем меньше размер массива, тем лучше.
begin...end (2006-02-05 08:20:00) [20]> Defunct © (05.02.06 08:07) [4]
> packed распространяется только на record.
Packed распространяется не только на record.