Форум: "Начинающим";
Текущий архив: 2015.09.10;
Скачать: [xml.tar.bz2];
ВнизНачало и размер буфера динамической переменной Найти похожие ветки
← →
Who_are_you? © (2014-04-22 11:22) [0]Всем здравия.
Извините, ранее не работал с динамическими переменными.
Перелапатил Инет, но остались вопросы.
В тексте ниже:
- правильно ли выделен размер массива (1900) в динамической памяти и ссылка на начало массива;
- лучше определить размер или лучше указать просто array of byte;
- что-то в программе не так - DataBuf_FT получает пачки "100,101,102,103" до конца 4к и не работает inc даже до 10;
- почему перед чтением DataBuf_FT оказывается вдруг заполнен числами от 104 до 110 ?
Вообще мне нужен динамический массив от 100 до 4к, чтоб я его мог заполнять и читать; и всегда знал его начало (адрес).
typе
D_B = array [1..1900] of byte; { массив для вывода }
Data_Bu = ^D_B;
var
Buf : Data_Bu; // массив для вывода
Data_Buf : Pbyte; // динамические данные
DataBuf_FT :array[0..4096] of byte; //
ct,i_rd : Longint;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
for ct:=0 to 4096 do DataBuf_FT[i_rd]:= 0;
New(Data_Buf);
Data_Buf:=@Buf; //начало массива - адрес буфера
for ct:=0 to 10 do // заполнение массива
begin
Data_Buf^:= ct+100; //
inc (Data_Buf);
end;
Data_Buf:=@Buf; //начало массива - адрес буфера
for i_rd:=0 to 4096 do // чтение массива
// Repeat
begin
DataBuf_FT[i_rd]:= Data_Buf^;
inc (Data_Buf);
end;
Dispose(Data_Buf);
end;
← →
junglecat (2014-04-22 11:50) [1]array of byte + SetLength
← →
sniknik © (2014-04-22 11:53) [2]> - лучше определить размер или лучше указать просто array of byte;
динамический массив гораздо удобнее чем самостоятельное выделение памяти под массив/указатели... раньше, в паскале когда не было динамических, именно так и делали. а сейчас зачем "париться"?
← →
MBo © (2014-04-22 12:15) [3]New(Data_Buf);
выделяется один байт, его адрес в Data_Buf
Data_Buf:=@Buf;
но тот адрес теряется, утечка памяти, а Data_Buf теперь указатель на указатель (неинициализированный, но его адресуемая память тут и не используется), т.е. на некую область стека (локальные данные процедуры)
for ct:=0 to 10 do // заполнение массива
begin
Data_Buf^:= ct+100; //
inc (Data_Buf);
end;
заполняются четыре байта переменной Buf
заполняются четыре байта переменной Data_Buf !! самого указателя! значениями 104-107
т.е. с четвертого по седьмой шаг указатель носится по дебрям памяти. Скорее всего, должны быть AV
Data_Buf:=@Buf;
теперь указатель снова указывает на стек
DataBuf_FT[i_rd]:= Data_Buf^;
а здесь читается из всяких разных адресов
Dispose(Data_Buf);
попытка освобождения невесть чего
← →
Who_are_you? © (2014-04-22 13:04) [4]Из ответа MBo:
я понял так, что нужно все выбросить и определить
var
Data_Buf :array of byte; // динамический массив
begin
for ct:=0 to 4096 do DataBuf_FT[i_rd]:= 0;
SetLength(Data_Buf,4096); // или 4096 менять на 100
// хотелось чтобы размер менялся по ходу заполнения
for ct:=0 to 10 do // заполнение массива
begin
Data_Buf[ct]:= ct+100; //
end;
for i_rd:=0 to 4096 do // чтение массива
begin
DataBuf_FT[i_rd]:= Data_Buf[i_rd];
end;
end;
Но как сделать, чтобы элементы массива Data_Buf[i_rd] были тоже динамическими Data_Buf^[i_rd] ?
← →
junglecat (2014-04-22 13:07) [5]> как сделать, чтобы элементы массива Data_Buf[i_rd] были
> тоже динамическими
array of array of byte?
← →
Германн © (2014-04-22 13:50) [6]
> Who_are_you? © (22.04.14 13:04) [4]
>
> Из ответа MBo:
> я понял так, что нужно все выбросить и определить
А зачем вообще все это?
← →
Who_are_you? © (2014-04-22 14:46) [7]А зачем вообще все это?
C динамическими переменными комп работате в N раз быстрее.
Я хочу, чтобы массив имел динамический размер, чтобы меньше занимать памяти для слабых старых компьютеров.
Раньше я делал так:
type
D_B = array[0..4096] of byte; { массив для вывода }
var
Data_Buf : ^D_B; // динамический массив
DataBuf_FT : array[0..4096] of byte; //
ct,i_rd : Longint;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
for ct:=0 to 4096 do DataBuf_FT[i_rd]:= 0;
New(Data_Buf);
for ct:=0 to 10 do // заполнение массива
begin
Data_Buf^[ct]:= ct+100; //
end;
for i_rd:=0 to 4096 do // чтение массива
begin
DataBuf_FT[i_rd]:= Data_Buf^[i_rd];
end;
Dispose(Data_Buf);
end;
← →
MBo © (2014-04-22 14:46) [8]Если доступ к элементам частый, а длина меняется редко, то выгоднее динамический массив.
Если длина меняется часто - удобнее будет список.
Элементы массива или списка тоже могут быть массивами или списками.
Лучше описать реальную задачу, тогда советы будут конкретнее.
← →
Who_are_you? © (2014-04-22 14:51) [9]MBo © (22.04.14 12:15) [3]
New(Data_Buf);
выделяется один байт, его адрес в Data_Buf
Data_Buf:=@Buf;
но тот адрес теряется, утечка памяти, а Data_Buf теперь указатель на указатель (неинициализированный, но его адресуемая память тут и не используется), т.е. на некую область стека (локальные данные процедуры)
for ct:=0 to 10 do // заполнение массива
begin
Data_Buf^:= ct+100; //
inc (Data_Buf);
end;
заполняются четыре байта переменной Buf
заполняются четыре байта переменной Data_Buf !! самого указателя! значениями 104-107
т.е. с четвертого по седьмой шаг указатель носится по дебрям памяти. Скорее всего, должны быть AV
??????????
Почему 4 байта переменной Buf и значениями 104-107, где об этом сказано?
И почему с четвертого по седьмой шаг указатель носится по дебрям памяти?
← →
MBo © (2014-04-22 15:40) [10]>Почему 4 байта переменной Buf
размер указателя - 4 байта, в него пишутся байты 100 - 103
>и значениями 104-107
а эти значения будут писаться по следующему адресу, где, скорее всего, лежит следующая локальная переменная Data_Buf
>И почему с четвертого по седьмой шаг указатель носится по дебрям памяти?
Первый байт Data_Buf замещается на 104, после этого прибавляется единица, и т.д.
← →
Who_are_you? © (2014-04-22 16:17) [11]MBo - класс !!!
Про размер указателя - 4 байта у меня где-то проскочило.
Подскажите, пожалуйста, а как сделать динамически изменяемый размер Data_Buf в примере ответа №7 ?
type
D_B = array[0..4096] of byte; { массив для вывода }
var
Data_Buf : ^D_B; // динамический массив
← →
MBo © (2014-04-22 16:33) [12]array of Byte + SetLength - вроде уже давно об этом речь идёт
но пример явно надуманный
← →
Who_are_you? © (2014-04-22 17:33) [13]1)
type
D_B = array[0..4096] of byte; { массив для вывода }
var
Data_Buf : ^D_B; // динамический массив
и
2)
var
Data_Buf :array of byte; // динамический массив
Неужели и в 1) и 2) случае работа с array по скорости будет одинакова?
Я проверял: разница по скорости между 1) и просто Var Data_Buf : array[0..4096] of byte; в n-раз. Зрительно очень заметно.
← →
Германн © (2014-04-22 17:45) [14]
> Я проверял: разница по скорости между 1) и просто Var Data_Buf
> : array[0..4096] of byte; в n-раз.
Что-то ты не то проверял.
← →
sniknik © (2014-04-22 17:48) [15]> Неужели и в 1) и 2) случае работа с array по скорости будет одинакова?
если не "выделываться" с тем чего не понимаешь (указателями), а писать "по канонам" (как в хелпе) то будет быстрее. т.к. оптимизатор "заточен" на стандарты, а не извращения... не, теоретически можно "обогнать", но знать "происходящее унутри" нужно очень хорошо.
← →
sniknik © (2014-04-22 17:53) [16]> Data_Buf : ^D_B; // динамический массив
вот это не заливна... не динамический массив, это указатель на массив.
← →
MBo © (2014-04-22 20:45) [17]>Я проверял
Давай посмотрим:
var
a: array[0..1024*1024*256] of Byte; //такой большой - глобальным должен быть
var
b: array of Byte;
i, s: Integer;
pb: PByte;
t: DWord;
begin
SetLength(b, 1024 * 1024 * 256);
t := GetTickCount;
for i := 0 to 1024 * 1024 * 256 - 1 do
s := s xor b[i];
Memo1.Lines.Add(Format("дин.массив %d", [GetTickCount - t]));
b := nil;
t := GetTickCount;
for i := 0 to 1024 * 1024 * 256 - 1 do
s := s xor a[i];
Memo1.Lines.Add(Format("стат.массив %d", [GetTickCount - t]));
t := GetTickCount;
pb := @a[0];
for i := 0 to 1024 * 1024 * 256 - 1 do begin
s := s xor pb^;
inc(pb);
end;
Memo1.Lines.Add(Format("стат. через указатель %d", [GetTickCount - t]));
GetMem(pb, 1024 * 1024 * 256);
t := GetTickCount;
for i := 0 to 1024 * 1024 * 256 - 1 do begin
s := s xor pb^;
inc(pb);
end;
Memo1.Lines.Add(Format("дин. выделенная память %d", [GetTickCount - t]));
Dec(pb, 1024 * 1024 * 256);
FreeMem(pb);
← →
Who_are_you? © (2014-04-23 11:02) [18]MBo !!! Еще раз спасибо за квалифицированную помощь.
Тест Ваш запустил, но немного уменьшил объемы, - иначе висит комп.
var
Form1: TForm1;
var
a: array[0..1024 * 1024*25] of Byte; //òàêîé áîëüøîé - ãëîáàëüíûì äîëæåí áûòü
var
b: array of Byte;
i, s: Integer;
pb: PByte;
t: DWord;
implementation
{$R *.dfm}
//>Я проверял
//Давай посмотрим:
procedure TForm1.Button1Click(Sender: TObject);
begin
SetLength(b, 1024 * 1024*25);
t := GetTickCount;
for i := 0 to 1024 * 1024*25 - 1 do
s := s xor b[i];
Memo1.Lines.Add(Format("äèí.ìàññèâ %d", [GetTickCount - t]));
b := nil;
t := GetTickCount;
for i := 0 to 1024 * 1024*25 - 1 do
s := s xor a[i];
Memo1.Lines.Add(Format("ñòàò.ìàññè& #226; %d", [GetTickCount - t]));
t := GetTickCount;
pb := @a[0];
for i := 0 to 1024 * 1024*25 - 1 do begin
s := s xor pb^;
inc(pb);
end;
Memo1.Lines.Add(Format("ñòàò. ÷åðåç óêàçàòåëü %d", [GetTickCount - t]));
GetMem(pb, 1024 * 1024*25);
t := GetTickCount;
for i := 0 to 1024 * 1024*25 - 1 do begin
s := s xor pb^;
inc(pb);
end;
Memo1.Lines.Add(Format("äèí. âûäåëåííàÿ ïàìÿòü %d", [GetTickCount - t]));
Dec(pb, 1024 * 1024*25);
FreeMem(pb);
end;
Cодержание Memo1 :
дин. массив 6760
стат. массив 8096
стат. через указатель 11795
дин. выделенная память 13182
Комментарии не требуются.
Когда я говорил выше, что проверял разницу по скорости,
то я читал с файла делал математические преобразования данных и выводил их на экран. Весь текст был один и тот же (большой не представляю поэтому).
Матрица была 4х32768. Менял только описание
type
vec4 =array [1..4] of double;
matrix = array[1..32768] of vec4;
matrixptr = ^matrix;
var
ms : matrixptr;
на статический.
Ещё раз Всем спасибо.
← →
MBo © (2014-04-23 11:12) [19]Какой компьютер использовался?
на i5-4670 c массивами в 256 мегабайт
дин.массив 546
стат.массив 577
стат. через указатель 562
дин. выделенная память 577
На Атлон 2 ГГц
дин.массив 1290
стат.массив 1290
стат. через указатель 1388
дин. выделенная память 1413
т.е. различия несерьёзные . На фоне хоть-какой то арифметики они вообще нивелируются.
(вообще я ожидал 10-20 % отставания динамического массива за счет другой адресации, но в данном случае, когда с другими данными работы не идет, эта адресация выполняется наиэффективнейшим способом c использованием [eax+edx])
← →
Who_are_you? © (2014-04-23 12:05) [20]На Core(TM) i5-2450M CPU 2.50GHz ОЗУ- 4 ГБ, Win7 64разрядная:
дин.массив 78
стат.массив 62
стат. через указатель 78
дин. выделенная память 63
Если n-раз запускать, то значения меняются на +/- 20.
Я думаю, что если задачу разбить на 3 программы, то данные будут другие.
На Toshiba Tecra 8000 Pentium II, Win 98, ОЗУ-128 MБ
дин. массив 6760
стат. массив 8096
стат. через указатель 11795
дин. выделенная память 13182
Здесь разница существенная.
← →
Who_are_you? © (2014-04-23 12:14) [21]Вопрос потому и был поднят, что необходимо быстродействие на старых компах.
← →
MBo © (2014-04-23 12:25) [22]Всё-таки сам по себе способ доступа к массиву не должен дать особого выигрыша в общем времени, если какие-то расчёты проводятся - он играет роль лишь при примитивной обработке или копировании.
← →
MBo © (2014-04-23 12:28) [23]В ветке уже предлагали озвучить реальную задачу. Возможно, кто-нибудь заметит, как исправить явные недочеты в реализации или предложит более эффективные алгоритмы.
← →
sniknik © (2014-04-23 12:43) [24]> или предложит более эффективные алгоритмы.
вся сила в плавках! (© сталевары)... т.е. алгоритмах. :)
← →
Who_are_you? © (2014-04-23 14:41) [25]
> В ветке уже предлагали озвучить реальную задачу. Возможно,
> кто-нибудь заметит, как исправить явные недочеты в реализации
> или предложит более эффективные алгоритмы.
Я уже озвучил ранее реальную задачу .
Если подробнее, то это:
- чтение с USB, COM или LPT-порта;
- математическая обработка и изменение формы представления;
- запись на винт, возможность чтения данных;
- графическая визуализация данных.
Программа написана и отлажена.
В настоящее время идёт перелапачивание программы,
т.к. она писалась и дописывалась в разное время и вид (внутренний) имеет ужасный.
К тому же, как я и писал, необходимо быстродействие на старых компах (типа:
Toshiba Tecra 8000 Pentium II, Win 98, ОЗУ-128 MБ), где работать приходится через LPT-порт.
Если кто-нибудь подскажет любые практические накатанные советы по корректировки программы - буду благодарен.
← →
Германн © (2014-04-23 15:11) [26]Что-то мне подсказывает что "чтение с USB, COM или LPT-порта" будет гораздо более медленной операцией чем работа с массивами в памяти.
← →
sniknik © (2014-04-23 15:40) [27]> Я уже озвучил ранее реальную задачу .
> Если подробнее, то это:
словесные описания не оптимизируются... в них нет алгоритмов. то что ты написал и что хотел/имел в виду MBo в [23] разные вещи... аднако.
> Если кто-нибудь подскажет любые практические накатанные советы по корректировки программы - буду благодарен.
совет (реально действенный) - найми программиста. жду благодарностей.
← →
Who_are_you? © (2014-04-23 16:34) [28]
> sniknik © (23.04.14 15:40) [27]
>
> совет (реально действенный) - найми программиста. жду благодарностей.
>
Спасибо за совет.
Но в реальной ситуации - он не реально действенный.
← →
sniknik © (2014-04-23 17:49) [29]да не, он реально действенный, чаще всего это единственно возможный вариант, все остальные кончаются ничем типа "помурыжат помурыжат и бросят, добавив в код еще немного ужасов, от себя".
ну вот кстати вариант ускорить (если у тебя там "линейная логика") это развести по разным потокам чтение с COM/LPT и все остальное... т.к. реально работа с такой периферией в основном (по затрачиваемому времени) заключается в ожидании ответа от нее.
сделаешь, ускоришь минимум в 2 раза... возможно.
← →
MBo © (2014-04-24 09:40) [30]> Если подробнее, то это:
> - чтение с USB, COM или LPT-порта;
> - математическая обработка и изменение формы представления;
>
> - запись на винт, возможность чтения данных;
> - графическая визуализация данных
Такими задачами занимается почти каждый, кто работает с железом.
>Если кто-нибудь подскажет любые практические накатанные советы по корректировки программы
Как можно дать конкретные советы по совершенно общему описанию?
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2015.09.10;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.052 c