Форум: "Основная";
Текущий архив: 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.047 c