Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.06.14;
Скачать: [xml.tar.bz2];

Вниз

Ускорение работы с динамическими массивами   Найти похожие ветки 

 
alertus   (2005-05-24 16:40) [0]

Добрый день, подскажите, пожалуйста, что делать.
Я написал довольно сложный алгоритм (моделирование и обучение нейронных сетей). Все восхитительно работает, но медленно :((

Написал несколько классов для работы с матрицами, нейронными слоями и нейронными сетями, там все построено на динамических массивов real.

Я делаю это так:
var
 a:array of array of real; //матрица
const
 w = 10; //ширина
 h = 5;  //высота
.....
Initialize(a);
SetLength(a,w*h);
i:=2; //столбец
j:=4; //строка
a[j+(i-1)*w]:=0.5; //установим елемент
Finalize(a);


Ну и т.п. все это забито в методы, например
TMatrix.SetElem(i,j:integer;r:real);

Я знаю, что с динамическими массивами можно еще работать так:
type
 myarray = array[1..1000] of real;
 pmyarray = ^myarray;
var
 a:pmyarray;
const
 w = 10;
 h = 5;
.....
i:=2;
j:=4;
getmem(a,w*h*sizeof(real));
a^[j+(i-1)*w]:=0.5;
freemem(a);


Но переписывать все очень долго и не знаю, будет ли выигрыш в скорости.
Может быть вообще надо отказаться от объектно-орентированной концепции, будет не так красиво, но быстро (под вопросом).

Подскажите, пожалуйста, кто сталкивался с подобными вопросами.
Может быть вообще скорость теряется не на динамических массивах, а на многочисленных арифметический операциях, как тогда ускорить их, я уже подумал о
asm
end;


 
begin...end ©   (2005-05-24 16:43) [1]

> alertus   (24.05.05 16:40)

> Я знаю, что с динамическими массивами можно еще работать
> так:
> ...
> не знаю, будет ли выигрыш в скорости

Скорость операции доступа к элементу массива не увеличится.


 
Alx2 ©   (2005-05-24 16:44) [2]

Сразу: избегай real. Замени на Single или Double.


 
Alx2 ©   (2005-05-24 16:50) [3]

Также передачу параметров в процедуры/функции лучше делать по адресу (например, procedure name(const Value : Double)).

Вообще, используй какой-нибудь профилер для поиска узких мест. Рекомендую VTune.


 
alertus   (2005-05-24 16:50) [4]

2Alx2 уже пробовал, скорость не меняется, а с single точность намного меньше (0.1+0.2=0.300000011920929), а насчет double: как написано в help"е Delphi, это real=double, если не стоит

{$REALCOMPATIBILITY ON}

Если же поставить эту диррективу, то real=real48 (на скорости тоже почти не сказывается).

PS
скорость я тестирую так:
a:=0.7648654;
b:=0.79645784;
for i:=1 to 100000 do
 for j:=1 to 100000 do
   c:=a*b;
label1.caption:="!!!";


 
Alx2 ©   (2005-05-24 16:52) [5]

>alertus   (24.05.05 16:50) [4]

> это real=double, если не стоит
>{$REALCOMPATIBILITY ON}

Сорри. Действительно.

Тогда нужно профилировать.


 
evvcom ©   (2005-05-24 16:57) [6]

А зачем array of array, если потом все равно работаешь как с одномерным?


 
begin...end ©   (2005-05-24 17:00) [7]

> Alx2 ©   (24.05.05 16:50) [3]

> Также передачу параметров в процедуры/функции лучше делать
> по адресу (например, procedure name(const Value : Double)).

const -- это НЕ передача по адресу.


 
alertus   (2005-05-24 17:02) [8]

Я работаю не как с одномерным, я написал процедуры типа
TMatrix.GetElem(i,j:integer).
А вообще я просто не понял, как обращаться по другому к двумерным массивам, если я обращусь a[2,3]:=10 то возникает вопрос, а какова ширина матрици??
Ведь до этого мы указали только количество элементов, например:
Initialize(a,25)


 
alertus   (2005-05-24 17:03) [9]

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


 
Alx2 ©   (2005-05-24 17:03) [10]

>begin...end ©   (24.05.05 17:00) [7]
A constant (const) parameter is like a local constant or read-only variable. Constant parameters are similar to value parameters, except that you can’t assign a value to a constant parameter within the body of a procedure or function, nor can you pass one as a var parameter to another routine. (But when you pass an object reference as a constant parameter, you can still modify the object’s properties.)
Using const allows the compiler to optimize code for structured- and string-type parameters. It also provides a safeguard against unintentionally passing a parameter by reference to another routine .

Here, for example, is the header for the CompareStr function in the SysUtils unit:

function CompareStr(const S1, S2: string): Integer;

Because S1 and S2 are not modified in the body of CompareStr, they can be declared as constant parameters.


 
Alx2 ©   (2005-05-24 17:05) [11]

>alertus   (24.05.05 17:03)

Без кода будет только телепатия :)
Высылай, если-что.


 
alertus   (2005-05-24 17:09) [12]

А что такое "профилер"??


 
begin...end ©   (2005-05-24 17:11) [13]

> Alx2 ©   (24.05.05 17:03) [10]

> It also provides a safeguard against unintentionally passing
> a parameter by reference to another routine .

Ну, и?


 
Alx2 ©   (2005-05-24 17:12) [14]

>alertus   (24.05.05 17:09) [12]

profiler - инструмент для построения "профиля" программы.
Профиль, если говорить карикатурно, - график "скорострельности" различных участков программы.


 
Alx2 ©   (2005-05-24 17:12) [15]

>begin...end ©   (24.05.05 17:11)
Я угадывать должен, что ты имеешь в виду?


 
begin...end ©   (2005-05-24 17:19) [16]

> Alx2 ©   (24.05.05 17:12) [15]

> It also provides a safeguard against unintentionally passing
> a parameter by reference to another routine .

Перевожу: "Это также обеспечивает защиту против непреднамеренной передачи параметра по ссылке в другую подпрограмму".

Теперь ответьте на вопрос: следует ли из этой фразы, что параметр с модификатором const передаётся по адресу, как Вы заявили в [3]?


 
Mx ©   (2005-05-24 17:26) [17]


> begin...end ©

Как я понял, const - это по адресу, но компилятор запрещает явное изменение ее значения. Скажем в передав по const массив record"ов мы сможем изменить значение его переменных, но не сможем изменить значение самой ссылки на массив, т.к. она const. Можно, кстати, проверить адреса - они совпадут.


> It also provides a safeguard against unintentionally passing
> a parameter by reference to another routine

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


 
Mx ©   (2005-05-24 17:30) [18]

Гм... правда здесь возникает другой вопрос: как по const передаются свойства? Видимо все гораздо хитрее...


 
begin...end ©   (2005-05-24 17:31) [19]

> Mx ©   (24.05.05 17:26) [17]

> Как я понял, const - это по адресу ...

Читаем процитированный выше хелп:

> Constant parameters are similar to value parameters, except
> that you can’t assign a value to a constant parameter within
> the body of a procedure or function, nor can you pass one
> as a var parameter to another routine.

и переводим:

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

Откуда следует, что const -- это передача по ссылке?

Да и в окне CPU всё видно, вообще-то.


 
begin...end ©   (2005-05-24 17:32) [20]

> Mx ©   (24.05.05 17:30) [18]

Какие свойства?


 
Alx2 ©   (2005-05-24 17:37) [21]

>begin...end ©   (24.05.05 17:19)

> Alx2 ©   (24.05.05 17:12) [15]

> It also provides a safeguard against unintentionally passing
> a parameter by reference to another routine .

>Перевожу: "Это также обеспечивает защиту против
>непреднамеренной передачи параметра по ссылке в другую
>подпрограмму".

>Теперь ответьте на вопрос: следует ли из этой фразы, что
>параметр с модификатором const передаётся по адресу, как Вы
>заявили в [3]?

Сорри, с выделенным фрагментом наврал. Конечно, именно из этой фразы не следует.

Но параметр передается по ссылке.

>Да и в окне CPU всё видно, вообще-то.

Вот-вот. Там и видно.


 
Mx ©   (2005-05-24 17:39) [22]


> begin...end ©

В качестве var"а свойство объекта мы не передадим, а через const пожалуйста. Это я имел ввиду.

Сейчас проверил: если передать record без const, то адреса - разные, а если через const - одинаковые.


> похожи на параметры по значению

Похожи не значат, что именно так.


 
alertus   (2005-05-24 17:42) [23]

Раз уж речь зашла.
Я так понимаю, var - это передача по ссылке, а const - нет, значит по значению

> It also provides a safeguard against unintentionally passing
> a parameter by reference to another routine.

То есть если программист не хочет нечаянно передать функции параметр по ссылке, чтобы та его не изменила ненароком, он пишет const...


 
Alx2 ©   (2005-05-24 17:42) [24]

> begin...end ©
Возможно, будет важным дополнением: если параметр целиком помещается в 4 байта, то передается по значению. Если нет - по ссылке.


 
begin...end ©   (2005-05-24 17:49) [25]

> Alx2 ©   (24.05.05 17:37) [21]

function Func1(Value: Integer): Integer;
begin
 Result := Value
end;

function Func2(var Value: Integer): Integer;
begin
 Result := Value
end;

function Func3(const Value: Integer): Integer;
begin
 Result := Value
end;

var
 I: Integer;
begin
 I := 1;
 Func1(I);
 Func2(I);
 Func3(I)
end.


>> Да и в окне CPU всё видно, вообще-то.
> Вот-вот. Там и видно.

Не знаю, что видно у Вас, а у меня видно следующее:

mov [esp],$00000001

mov eax,[esp]
call Func1

mov eax,esp
call Func2

mov eax,[esp]
call Func3


> Alx2 ©   (24.05.05 17:42) [24]

Замените в приведённом коде Integer на Extended. Что-то принципиально поменяется?


 
Mx ©   (2005-05-24 17:50) [26]


> Alx2 ©

Возможно. А как быть с параметрами типа Extended? Свойство, возвращаемое по функции тоже можно передать как Const, ссылки не будет, но значение больше 4 байт.


 
Alx2 ©   (2005-05-24 17:55) [27]

>begin...end ©   (24.05.05 17:49)

Сыплю пепел на голову. Спасибо за развенчивание моего мифа относительно const. Черт, а ведь был твердо уверен :)
Пошел учить матчасть.


 
begin...end ©   (2005-05-24 17:55) [28]

> Mx ©   (24.05.05 17:39) [22]

> В качестве var"а свойство объекта мы не передадим, а через
> const пожалуйста.

Конечно, не передадите. Свойство -- это ведь не переменная. И у него нет адреса. А вот значение -- есть.


 
Alx2 ©   (2005-05-24 18:12) [29]

И все-таки не пойму. Зачем нужно const extended передавать по значению? Только лишние траты. Чего-то я не учитываю...


 
malkolinge ©   (2005-05-24 18:34) [30]

VarArrayLock()


 
Mx ©   (2005-05-24 21:03) [31]


> begin...end ©
> Конечно, не передадите

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

Так как быть с record"ом? В случае передачи по const адрес переменной один и тот же, а в случае без const - разный.


 
Mx ©   (2005-05-24 21:15) [32]

Совсем интересно, может кто разъяснит? Судя по CPU View во всех трех случаях, после замены типа формального параметра на простенький record с двумя Integer"ами, в EAX помещается ESP, однако оператор @ показывает в случае Func1 все-равно возвращает число, отличное от Func2/Func3:


type
 TM = record
   S: Integer;
   B: Integer;
 end;

function Func1(Value: TM): Integer;
begin
Result := Value.S;
end;

function Func2(var Value: TM): Integer;
begin
Result := Value.S;
end;

function Func3(const Value: TM): Integer;
begin
Result := Value.S;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
I: TM;
begin
I.S := 1;
I.B := 2;
Func1(I);
Func2(I);
Func3(I)
end;


в CPU View:

MOV  [ESP],$1
MOV  [ESP+$4],$2

MOV  EAX,ESP
CALL FUNC1

MOV  EAX,ESP
CALL FUNC2

MOV  EAX,ESP
CALL FUNC3


 
VMcL ©   (2005-05-24 21:41) [33]

>>Alx2 ©   (24.05.05 16:50) [3]

"const" имеет особый смысл в плане оптимизации для объектов с управляемым временем жизни (long strings, dynamic arrays, interfaces) и объектов структурного (record) или массивного (array) типа.


 
Mx ©   (2005-05-24 21:45) [34]

Я тока не понял почему в EAX все разы записывается ESP, но "собака"Value в Func1 возвращает адрес отличный от TForm1.Create, Func2, Func3 - в них он идентичен.


 
GuAV ©   (2005-05-25 00:25) [35]

Mx ©   (24.05.05 21:45) [34]

Записи, которые не помещающиеся в маш слово, всегда передаются по ссылке. Для таких записей переданных без const/var/out при необходимости создаётся рабочая копия ( "собака"Value возвращает именно её адрес).

см [33]


 
Defunct ©   (2005-05-25 00:35) [36]

Mx ©   (24.05.05 21:45) [34]

Вы в курсе что такое ESP? Если нет, тогда [35] трудно будет совместить с вашим CPU View из [32].


 
GuAV ©   (2005-05-25 01:07) [37]

к [35]

Разумеется, рабочая копия создаётся кодом вызываемой функции.

Это верно для соглашений register и pascal.
для cdecl или stdcall (safecall) запись переданная без const/var/out педедаётся по значению.


 
Mx ©   (2005-05-25 02:19) [38]


> Defunct ©

В курсе в курсе...


> GuAV ©
> Разумеется, рабочая копия создаётся кодом вызываемой функции.

Теперь понятно.


 
alertus   (2005-05-25 10:36) [39]

А какой вывод из этого всего можно сделать, как быстрее работать будет.
Я так понимаю, динамический массив всегда по ссылке передается, потому что передается не сам массив данных, а только адрес первого элемента и функция уже производит действия с елементами, расположенными по смещению от этого адреса:
a^[17]:=3.14;


 
Mx ©   (2005-05-25 10:58) [40]

Если ты имеешь ввиду разницу в скорости работы через GetMem или SetLenght, то это уже обсуждалось, разницы никакой.



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

Форум: "Основная";
Текущий архив: 2005.06.14;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.039 c
9-1110559906
Кирилл
2005-03-11 19:51
2005.06.14
*.MTL


1-1117099653
pavel_guzhanov
2005-05-26 13:27
2005.06.14
Работа с PopupMenu


3-1115549163
_e_u_
2005-05-08 14:46
2005.06.14
Добавление строки в таблицу ;)


4-1114245891
dron-s
2005-04-23 12:44
2005.06.14
Куда установлена система


1-1117568825
Demonix
2005-05-31 23:47
2005.06.14
объект Edit1 и командная строка





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский