Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Pointer->Integer->Pointer


Страницы:   1 2 3 4 5

alertus ©   (2005-05-27 17:36:00) 

Подскажите, пожалуйста, если я пишу так:

a:^real;
p:^real;
....
getmem(a,100*sizeof(real));
p:=pointer(integer(a)+0);
p^:=0.347;
p:=pointer(integer(a)+8);
p^:=0.764;
p:=pointer(integer(a)+16);
p^:=0.764;
....


Похоже ли это на работу динамического массива и какова будет разница в скорости??


Defunct   (2005-05-27 19:08:00) [61]

Verg ©   (27.05.05 18:52) [17]

Допускается же умножение индексного регистра при адресации массивов. пример:

 mov EAX, [EBX + ESI*8]


begin...end   (2005-05-27 19:06:00) [62]

> alertus ©   (27.05.05 19:03) [19]

> а что, если используются близкие адреса, то это будет быстрее??

Дело не столько в близких адресах, сколько в облегчении вычисления индексов. И об этом я уже говорил Вам в предыдущей ветке.

var
 a: Pointer;
 p: ^Real;
begin
 GetMem(a, 100 * sizeof(Real));
 p := a;
 p^ := 0.347;
 Inc(p);
 p^ := 0.764;
 Inc(p);
 p^ := 0.764;
 ...
end.


alertus   (2005-05-27 19:03:00) [63]


> а если да, то дин.структуры нафих не нужны - один раз распределил
> память и заполняй ее сколь угоднго "эффективно", хоть  на
> асме, хоть на хрясме)

Размеры матриц изначально не известны на первой, ни второй, ни ризультата, но в ходе программы они не меняются.


> Она (вторая функция) - реализована неверно.

Да, я теперь заметил, торопился когда писал.


> Кроме того, с точки зрения оптимизации работы с памятью
> может быть эффективно предварительно транспонировать одну
> из матриц.

Вообще если говорить о моей программе, то у меня вторая матрица - это транспонированная первая (это аппроксимация алгоритма Ньютона для нахождения производной функции нескольких переменных от по двум переменным), а что, если используются близкие адреса, то это будет быстрее??

Всем огромное спасибо, попробую совместить все советы.


-=XP=-   (2005-05-27 18:55:00) [64]

А причём тут SizeOf(pointer)?

Типа опечатка. Там дальше написано: SizeOf(real)

:)


Verg   (2005-05-27 18:52:00) [65]


> Она длится 2.7 секунды, уже лучше чем 4,


Это логично. Она (вторая функция) - реализована неверно. Экономия времени достигнута отсутствием требуемого умножения смещения от указателя на sizeof(real). Реально вычисляются адреса ячеек, как будь-то они размером 1 (байт).
А вообще задумайся - обход столбца одной матрицы и строки другой делаются строго последовательно. Т.о. если уж так хочется оптимизировать, то надо от прямого индексирования, сопровождающегося "в лоб" вычислением адреса через i,j и умножением на sizeof(real) на каждом шаге, переходить на суммирование индексных смещений (наращивание на каждом шаге). Т.о. ты избавишься от операций умножения для вычислений физического адреса ячейки матрицы.


begin...end   (2005-05-27 18:50:00) [66]

> -=XP=- ©   (27.05.05 17:45) [2]

> Лучше использовать не +0, +8, а +SizeOf(pointer) * ItemIndex

А причём тут SizeOf(pointer)?


MBo   (2005-05-27 18:41:00) [67]

Кроме канонического алгоритма вычисления произведения матриц, существуют и более сложные - Винограда, Штрассена. На порядок они выигрыша не дадут, а в пару раз при твоих размерах - возможно. Кроме того, с точки зрения оптимизации работы с памятью может быть эффективно предварительно транспонировать одну из матриц, чтобы обращение к памяти шло подряд, а не скачками. И еще - использование SSE-иструкций современных процессоров - при программировании на ASM или использовании соответствующих компиляторов - може привести к ускорению еще в несколько раз.


Digitman   (2005-05-27 18:23:00) [68]


> хочу написать свою функцию на Dephi


это похвально.
и перевешивает любые иные аргументы.

размер матрицы-результата тебе известен ?

думаю - да.

а если да, то дин.структуры нафих не нужны - один раз распределил память и заполняй ее сколь угоднго "эффективно", хоть  на асме, хоть на хрясме)


alertus   (2005-05-27 18:18:00) [69]


> Какой процессор?

Дома Athlon 1000, а на работе, где я сейчас - Athlon 800.


alertus   (2005-05-27 18:17:00) [70]


> В новых версиях Mаtlab'а появился встроенный компилятор,
> но он позволяет (если не ошибаюсь) компилить matlab'овские
> функции в только dll.


Да, это так, но, как я понимаю, если я напишу на матлабе функцию перемножения матриц и сделаю dll, то этой dll нужна другая, где реализовано само умножения, я с трудом понимаю где ее искать, и я не знаю точно как передавать параметры.

Ну и, в конце концов, я хочу написать свою функцию на Dephi.


> Дело в том, что в MatLab'е интерпретатор и у меня Matlab
> работает медленнее, чем тот же код переписанный на Delphi,
> причём в разы.

Да, это абсолютно так для циклов и программ, но если взять отдельно функцию перемножения матриц, то ситуация резко меняется в противоположную сторону.


MBo   (2005-05-27 18:16:00) [71]

Какой процессор?


alertus   (2005-05-27 18:12:00) [72]

А что насчет менеджера памяти, я так понимаю, есть такой тип TMemoryManeger, он создается вместе с приложением (TApplication).
Он управляет всей памятью, которая требуется приложению, в том числе и динамическими массивами, но он проверяет не превышены ли текущие границы динамического массива и т.п.
Это, как я понимаю и есть управляющая структура, а я хочу ее обойти или поменьше использовать.
Я совсем не уверен что это все правильно, но я ищу способы ускорить мою программу.

> Скорее всего, у Вас алгоритм другой, нежели в MathLab.

Я думаю, что для перемножения матриц другого алгоритма просто не существует в природе (возможно я не прав). Я использую такой:

var
 m1:array[1..2,1..3] of real;
 m2:array[1..3,1..2] of real;
 mr:array[1..2,1..2] of real;
 temp:real;
begin
 for i:=1 to 2 do begin
   for j:=1 to 2 do begin
     temp:=0;
     for k:=1 to 3 do begin
       temp:=temp+m1[i,k]*m2[k,j];
     end;
     mr[i,j]:=temp;
   end;
 end;
end;


Я реализовал свою небольшую прогараммку:

procedure TForm1.Button1Click(Sender: TObject);
var
 i,j,k:integer;
 temp:real;
 t1,t2:real;
 pt:^real;
 off:integer;
begin
 m1.w:=400;
 m1.h:=800;
 getmem(m1.pint,400*800*sizeof(real));
 m2.w:=800;
 m2.h:=400;
 getmem(m2.pint,800*400*sizeof(real));
 mr.w:=400;
 mr.h:=400;
 getmem(mr.pint,400*400*sizeof(real));
 for i:=1 to 400 do begin
   for j:=1 to 400 do begin
     temp:=0;
     for k:=1 to 800 do begin
       pt:=pointer(integer(m1.pint)+(i-1+(k-1)*m1.w));
       t1:=pt^;
       pt:=pointer(integer(m2.pint)+(k-1+(i-1)*m1.h));
       t2:=pt^;
       temp:=temp+t1*t2;
     end;
     pt:=pointer(integer(mr.pint)+(i-1+(j-1)*m1.h));
     pt^:=temp;
   end;
 end;
end;


Она длится 2.7 секунды, уже лучше чем 4, да и размер матриц больше, только это не объективно, потому что я на другом компьютере, хотя процессоры почти одинаковые.


Lin7   (2005-05-27 18:11:00) [73]


> alertus ©   (27.05.05 17:47) [3]
> Я столкнулся с программированием на Matlab, там перемножение
> двух матриц 300x700 элементов real занимает около 1/4 секунды,
> а у меня на Delphi с использованием динамических массивов
> - 4 сек.


Может приведёшь свой код? Дело в том, что в MatLab'е интерпретатор и у меня Matlab работает медленнее, чем тот же код переписанный на Delphi, причём в разы. В новых версиях Mаtlab'а появился встроенный компилятор, но он позволяет (если не ошибаюсь) компилить matlab'овские функции в только dll.


Digitman   (2005-05-27 17:58:00) [74]


> Меня беспокоит то, что любая управляющая структура уменьшает
> скорость


при обращении по чтению - ровно на одну-две маш.инструкции.

мизер.


> специально делаю все на наиболее низком уровне


начинать нужно со своего менеджера памяти (адаптированного под конкр.задачи), а не с динамических структур, иначе все твои усилия будут сведены на нет


> хочу попробовать на asm'е это сделать


попробуй.
тем более что садомазо нынче в моде)


-=XP=-   (2005-05-27 17:54:00) [75]

Тут проблема не с динамическими массивами.
Скорее всего, у Вас алгоритм другой, нежели в MathLab.


alertus   (2005-05-27 17:52:00) [76]


> любой дин.тип данных предусматривает упр.структуру ... она
> у тебя ГДЕ ?

Меня беспокоит то, что любая управляющая структура уменьшает скорость, я специально делаю все на наиболее низком уровне, хочу попробовать на asm'е это сделать...


alertus   (2005-05-27 17:50:00) [77]


> Лучше использовать не +0, +8, а +SizeOf(real) * ItemIndex


Да, я так и хотел сделать в дальнейшем.

А как насчет скорости или другой реализации??


Digitman   (2005-05-27 17:50:00) [78]


> Почему не похоже


по кочану.

любой дин.тип данных предусматривает упр.структуру ... она у тебя ГДЕ ?


alertus   (2005-05-27 17:47:00) [79]

Почему не похоже, ведь у меня получился массив из 100 элементов типа real, к каждому из которых я имею доступ.
И если я изначально не знаю размер массива, то я могу его задать в ходе выполнения программы (после мне его менятьт не потребуется).

Я столкнулся с программированием на Matlab, там перемножение двух матриц 300x700 элементов real занимает около 1/4 секунды, а у меня на Delphi с использованием динамических массивов - 4 сек.
Matlab написан на C++, там динамические массивы объявляются так:
float *a.

В общем я хочу ускорить операции с динамическими массивами, судя по Matlab'у это возможно.

Может быть кто-нибудь знает как это запрограммировано на Matlab'е??


-=XP=-   (2005-05-27 17:45:00) [80]

Похоже. Но и только.

Лучше использовать не +0, +8, а +SizeOf(pointer) * ItemIndex

А зачем так изголяться? Чем динамические массивы не подошли?
Или конструкция типа:

{$RANGECHECKS OFF}
type
 PRealArray = ^TRealArray;
 TRealArray = array[0..0] of real;
var
 A: PRealArray;
begin
 GetMem(A, 100 * SizeOf(real));
 A^[2] := 0.764;
 ...


Страницы:   1 2 3 4 5

Наверх

Титульная страница Поиск, карта сайта Написать письмо