Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.044 c
15-1418333424
Юрий
2014-12-12 00:30
2015.09.10
С днем рождения ! 12 декабря 2014 пятница


2-1397744469
NIK_NIK
2014-04-17 18:21
2015.09.10
Combobox в DBGrid


2-1392624704
alexdn
2014-02-17 12:11
2015.09.10
Раскрасить Edit


2-1394909781
alexdn
2014-03-15 22:56
2015.09.10
Сохранить содержимое PaintBox в файл


2-1396405670
Drowsy
2014-04-02 06:27
2015.09.10
TDUPM





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский