Главная страница
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.01 c
15-1215962143
Дмитрий_С
2008-07-13 19:15
2008.08.31
Время жизни объекта.


1-1197276566
BoxTer
2007-12-10 11:49
2008.08.31
Копирование данных между листами Excel


2-1216927230
self.name
2008-07-24 23:20
2008.08.31
компонент внутри компонента...


2-1216883464
kernel
2008-07-24 11:11
2008.08.31
Си => Паскаль


8-1184936230
DmitriyZ
2007-07-20 16:57
2008.08.31
Как в Delphi сгенерировать звук произвольной частоты и вывести ег