Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.06.29;
Скачать: CL | DM;

Вниз

Динамические массивы - правильно ли я понял 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;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.029 c
3-1116577596
MAGix
2005-05-20 12:26
2005.06.29
Непонятный глюк в Locate


3-1116151960
_e_u_
2005-05-15 14:12
2005.06.29
добавление полей в ADOQuery, что требуется?


1-1117582199
TrueCoder
2005-06-01 03:29
2005.06.29
Ошибка "Out of memory"


3-1116402505
SLP
2005-05-18 11:48
2005.06.29
копирование результатов запроса в буфер обмена


8-1110129109
anamal
2005-03-06 20:11
2005.06.29
Как убрать мигание?