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

Вниз

Как использовать movups в Asm в Delphi ?   Найти похожие ветки 

 
Anton   (2007-12-09 02:58) [0]

Как средствами Дельфи можно выравнивать массив на 16 байт?
Для увеличения скорости програмы сделал asm всавку, но на невыровненных по 16 байт массивах могу использовать только movups, а хочется использовать movaps.


 
Юрий Зотов ©   (2007-12-09 07:38) [1]

Выравнивание в D7  - максимум на 8 байт. Возможно, в более современных версиях есть и на 16 (посмотрите директиву компилятора {$A}).


 
Юрий Зотов ©   (2007-12-09 08:55) [2]

Вот искусственный способ выравнивания самого массива и его элементов на 16 байт. Работает независимо от директив компилятора, но я совершенно не уверен, что в этом способе есть практический смысл. Это решайте сами.

const
 LowArrayIndex = 0;
 HighArrayIndex = 99;

type
 TArrayElementType = Integer;

 TElementRecord = packed record
   Element: TArrayElementType;
   Dummy: packed array[1..(16 - SizeOf(TArrayElementType))] of byte;
 end;

 TArray = packed array[LowArrayIndex..HighArrayIndex] of TElementRecord;
 PArray = ^TArray;

 TArrayContainer = packed record
   Offset: packed array[1..16] of byte;
   Data: TArray;
 end;

var
 ArrayContainer: TArrayContainer;
 PData: PArray;

procedure TForm1.FormCreate(Sender: TObject);
begin
 PData := PArray(@ArrayContainer);
 while (Cardinal(PData) mod $10) <> 0 do
   PData := PArray(Cardinal(PData) + 1);
 Caption := IntToHex(Cardinal(PData), 8);  
end;


 
guav ©   (2007-12-09 12:53) [3]

Если выделять через VirtualAlloc, то данные будут выровнены на границу страницы памяти (это больше чем 16 байт). Однако выделение там тоже постраничное, потому неэффективно выделять таким образом небольшие объёмы. Если массив достаточчно большой, то использовать VirtualAlloc/VitrualFree - самое простое решение.


 
Pavia ©   (2007-12-10 08:56) [4]

Предлогаю использовать следующии две процедуры.


procedure GetMemA16(var p:Pointer; Size:Integer);
var t:Pointer;
i:Integer;
begin
GetMem(t,Size+16);
i:=((DWord(t) div 16)+1)*16;
p:=Pointer(i);
DWord(Pointer(DWord(p)-4)^):=DWord(t);
end;

procedure FreeMemA16(p:Pointer);
begin
if p<> nil then p:=Pointer(Pointer(DWord(p)-4)^);
FreeMem(p);
end;


 
Сергей М. ©   (2007-12-10 09:00) [5]


> Anton   (09.12.07 02:58)


Аллокируй память под массив средствами менеджера в составе msvcrXX.dll - там выравнивание как раз 16-байтное.


 
Юрий Зотов ©   (2007-12-10 09:04) [6]

Народ, получить кусок памяти по адресу, кратному 16 - это только одна часть вопроса. Но надо же еще и все элементы массива выровнять.


 
Сергей М. ©   (2007-12-10 09:21) [7]


> надо же еще и все элементы массива выровнять


Это надо еще умудриться напортачить с выравниванием внутри самого массива)


 
Юрий Зотов ©   (2007-12-10 09:27) [8]

> Сергей М. ©   (10.12.07 09:21) [7]

Однако же, сами по себе элементы массива на 16-байтовую границу тоже не выровняются, какой-то фокус для этого все же нужен. Isn"t it?


 
Сергей М. ©   (2007-12-10 09:39) [9]


> Юрий Зотов ©   (10.12.07 09:27) [8]


Речь идет конкретно о сабжевых маш.инструкциях.
Они требуют выравнивание операндов на сабжевую границу.
Операндами являются нач.адреса блоков памяти.
За содержимое же блока памяти, на которую ссылается операнд-источник, отвечает сам программист - процессору оно по барабану.

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


 
Юрий Зотов ©   (2007-12-10 09:47) [10]

> Сергей М. ©   (10.12.07 09:39) [9]

> умудриться вызвать исключение при пересылке действительно можно

И легко. Если, например, пересылать произвольную часть массива с НЕвыравненными элементами.


 
DiamondShark ©   (2007-12-10 13:53) [11]

Прямо клуб телепатов.

А посмотреть в Instruction Set Reference с каким типом данных работают упомянутые инструкции -- это ниже своего достоинства.


 
@!!ex ©   (2007-12-11 09:38) [12]

> [0] Anton   (09.12.07 02:58)

разница между этими командами минимальна. Больше потеряешь выравнивая поля.
Лично я пользуюсь movUps и горя не знаю. ;)



Страницы: 1 вся ветка

Текущий архив: 2008.08.31;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.014 c
15-1215717772
Пробегал2....
2008-07-10 23:22
2008.08.31
Куда двигаться после delphi?


2-1216986372
navigator1
2008-07-25 15:46
2008.08.31
Файл в константу


1-1197536361
Soulless
2007-12-13 11:59
2008.08.31
qreport,. cannot create file


15-1215691880
zinetz_victor
2008-07-10 16:11
2008.08.31
Как увеличить приоритет для flash activeX?


15-1215785201
Interior
2008-07-11 18:06
2008.08.31
Allegro - что за зверь?