Форум: "Основная";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];
ВнизДинамические массивы - правильно ли я понял help? Найти похожие ветки
← →
evvcom © (2005-06-02 11:09) [40]Я уже проверил.
type
TRecord = record
c: Char;
w: WORD;
w1: WORD;
end;
const
ac1: TRecord = (c: "A"; w: $10; w1: $55);
ac2: TRecord = (c: "B"; w: $20; w1: $AA);
var
a1: array[0..1] of TRecord;
a2: packed array[0..1] of TRecord;
begin
a1[0] := ac1;
a1[1] := ac2;
a2[0] := ac1;
a2[1] := ac2;
end;
компилятор не делает разницы между packed array и не packed. Оба массива занимают по 12 байт:
41 00 10 00 55 00 42 00 20 00 AA 00
все hex
← →
evvcom © (2005-06-02 11:10) [41]+ А вот элементы массива по 6 байт, т.е. SizeOf(TRecord)
← →
Defunct © (2005-06-02 11:15) [42]> evvcom
ок, теперь все понятно. Вы были правы в [36].
> компилятор не делает разницы между packed array и не packed
А как же заставить компилятор чтобы массив был НЕ упакованым?
т.е. то про что говорил ЮЗ:
когда отсутствие этой директивы компилятором НЕ игнорируется
← →
Суслик © (2005-06-02 11:17) [43]
> А как же заставить компилятор чтобы массив был НЕ упакованым?
>
А оно вам надо?
← →
Суслик © (2005-06-02 11:20) [44]
> [42] Defunct © (02.06.05 11:15)
С трудом могу представить, когда это нужно. Как я говорил на это кладут сами разработчики borland. Не скажу где (т.к. не помню), но я вдиел в глубинах vcl игнорирование packed, хотя по месту это было необходимо.
Я сейчас постю и читаю группы на borland.com. Будет время спрошу про это.
← →
Anatoly Podgoretsky © (2005-06-02 11:24) [45]Defunct © (02.06.05 10:41) [34]
Достатоточно ли объявить packed array of TRecord, чтобы неупакованые записи стали упаковаными в массиве?
В данном контексте packed относится к самому массиву, а не элементам записи.
← →
Defunct © (2005-06-02 11:30) [46]> Суслик
Честно говоря - надо. Иначе бы и не спрашивал. Некоторые SSE команды работают только с данными, выровненными на границу QWORD иначе exception.
← →
evvcom © (2005-06-02 11:32) [47]
> А как же заставить компилятор чтобы массив был НЕ упакованым?
...
> Честно говоря - надо.
type
TRecord = record
c: Char;
w: WORD;
w1: WORD;
reserved: WORD;
end;
← →
Alx2 © (2005-06-02 11:33) [48]Defunct © (02.06.05 11:30) [46]
Кажется, есть аналоги для невыровненных данных.
← →
Defunct © (2005-06-02 11:39) [49]evvcom © (02.06.05 11:32) [47]
На данный момент именно так и поступаю.
Alx2 © (02.06.05 11:33) [48]
Но они работают медленнее почти в 2 раза
речь о
movdqa
и
movdqu
← →
Alx2 © (2005-06-02 12:03) [50]Defunct © (02.06.05 11:39) [49]
Увы. Компилятор Delphi (по крайней мере D6) не умеет делать требуемое выравнивание.
Чтобы это обойти, в критичных по скорости участках, я использую DLL, скомпилированные Intel C++ compiler. У него, кстати, кроме уже стандартных MMX, SSE, SSE2, SSE3 (в частности, для них он автоматом производит векторизацию и распараллеливание) есть оптимизация и под 64-битную архитектуру Itanium - пока еще большая редкость.
← →
begin...end © (2005-06-02 12:08) [51]> Defunct © (02.06.05 10:01) [28]
> Возможены случаи когда не будут.
Если утверждаете, то, вероятно, можете привести пример. Хотелось бы увидеть.
> SizeOf(<Record>) = 31, будут или не будут?
Будут.
> Defunct © (02.06.05 10:29) [31]
> TArray = packed array of TRecord
> Будет ли TArray соответствовать вышесказанному?
TArray будет упакованным, а его элементы будут неупакованными.
> Defunct © (02.06.05 10:41) [34]
> packed = упакованый.
> не обращаясь к справке, только по смыслу этого слова можно
> допустить, что независимо от компилятора каждое поле упакованой
> структуры будет размещено байт к байту с другими полями.
> Вот собсно в этом вопрос, так ли это.
Если запись объявлена с packed, то поля записи будут прижаты.
Если массив объявлен с packed, то элементы массива будут прижаты.
Если массив объявлен без packed, то элементы всё равно будут прижаты.
> Достатоточно ли объявить packed array of TRecord, чтобы
> неупакованые записи стали упаковаными в массиве?
Конечно, нет. Потому что в данном случае packed относится к размещению элементов массива, а не к размещению полей в этих элементах.
А если бы при таком объявлении записи упаковывались, как тогда выглядело бы присваивание значения элементу такого массива? По-Вашему, компилятор будет брать каждое поле из присваиваемой записи и помещать его в соответствующее поле упакованного элемента массива, вместо того чтобы скопировать целиком неупакованную запись?
По-моему, всё логично и понятно. Кроме того, что массивы всегда (независимо от наличия packed) упаковываются.
← →
TUser © (2005-06-02 12:08) [52]> > А как же заставить компилятор чтобы массив был НЕ упакованым?
Можно обявить array of TCoolRecord, где в TCoolRecord забить нужное кол-во бополнительных полей соотвествующего размера, например
TCoolRecord =
record
B1, B2: boolean; // 2 байта
C1, С2, С3: shortint; // 3 байта
Zero: array [0..2] of byte; // not used
end;
Интересно, не с этим ли связано появление reserved агрументов в некоторых API функциях?)
← →
Defunct © (2005-06-02 12:18) [53]> begin...end
Все было просто отлично, доходчиво и логично, до вот этого:
По-Вашему, компилятор будет брать каждое поле из присваиваемой записи и помещать его в соответствующее поле упакованного элемента массива, вместо того чтобы скопировать целиком неупакованную запись?
Обязательно надо было ложку дёгтя в бочку мёда засунуть?
Было бы "по-моему" еще неизвестно как сделал бы.
> не с этим ли связано появление reserved агрументов в некоторых API функциях
Вполне возможно.
← →
begin...end © (2005-06-02 12:23) [54]> Defunct © (02.06.05 12:18) [53]
> Обязательно надо было ложку дёгтя в бочку мёда засунуть?
> Было бы "по-моему" еще неизвестно как сделал бы.
Я просто не понял, как Вы себе представляете действия компилятора в данном случае. Потому и спросил.
← →
evvcom © (2005-06-02 12:39) [55]Кстати, переделал код:
type
TRecord = record
dw: DWORD;
c: Char;
end;
const
ac1: TRecord = (dw: $11111111; c: "A");
ac2: TRecord = (dw: $22222222; c: "B");
var
a1: array[0..1] of TRecord;
a2: packed array[0..1] of TRecord;
begin
a1[0] := ac1;
a1[1] := ac2;
a2[0] := ac1;
a2[1] := ac2;
end;
Компилятор между этими массивами опять не видит никакой разницы, но результат теперь такой:
11 11 11 11 41 00 00 00
22 22 22 22 42 00 00 00
Проверил SizeOf(TRecord), теперь он =8, хотя в предыдущем был =6. Вот этим 8 и 6 я что-то объяснения найти не могу пока.
← →
Sapersky (2005-06-02 15:15) [56]Логика выравнивания полей неупакованных записей довольно хитрая, это не просто "расставить поля по адресам кратным 4".
См. хелп: Object Pascal Reference \ Memory management \ Record types
Массивы, видимо, выравниваются по такому же принципу.
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.044 c