Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2015.09.10;
Скачать: CL | DM;

Вниз

Начало и размер буфера динамической переменной   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.088 c
15-1420407002
Юрий
2015-01-05 00:30
2015.09.10
С днем рождения ! 5 января 2015 понедельник


15-1415606556
Rouse_
2014-11-10 11:02
2015.09.10
Протестируйте плз код на AMD


15-1415217828
Jeer
2014-11-05 23:03
2015.09.10
С днем военного разведчика!


2-1393339999
Ден99
2014-02-25 18:53
2015.09.10
7 zip.dll


3-1304412780
OW
2011-05-03 12:53
2015.09.10
Вот опять Odac начинает глупости пороть.. ORA-00932