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

Вниз

Объявление "лишних" переменных в процедуре.   Найти похожие ветки 

 
Riply ©   (2007-08-27 16:41) [0]

Здравствуйте !
Допустим, у нас есть следующее:
некая глобальная переменная GlobEntrySize: DWord,
значение которой может оказаться не равно ENTRY_SIZE_1024
на одном из 10 тысяч подопытных дисков
и
рекурсивная процедура FileRecordScanIO,
которая вызывается очень много раз для каждого конкретного диска.

var
GlobEntrySize: DWord;

function _FileRecordScanIO_1024(const ObjLcn: _LCN; const pObjName: PNTFS_Name; const pScan: PMFT_ScanParamsW): DWord;
var
Buff: array[0..pred(ENTRY_SIZE_OUTPUT_1024)] of Byte;
begin
Result := _FileRecordParsingIO(@Buff, ObjLcn, pObjName, pScan);// некая обработка
end;

function _FileRecordScanIO(const ObjLcn: _LCN; const pObjName: PNTFS_Name; const pScanW: PMFT_ScanParamsW): DWord;
var
pBuffer: PByte;
begin
pBuffer := GetMemory(GlobEntrySize);
try
 Result := _FileRecordParsingIO(pBuffer, ObjLcn, pObjName, pScanW);
finally
 FreeMem(pBuffer);
end;
end;

function FileRecordScanIO(const ObjLcn: _LCN; const pObjName: PNTFS_Name; const pScanW: PMFT_ScanParamsW): DWord;
begin
if GlobEntrySize > ENTRY_SIZE_1024
 then Result := _FileRecordScanIO(ObjLcn, pObjName, pScanW)
 else Result := _FileRecordScanIO_1024(ObjLcn, pObjName, pScanW);
end;


Имеет ли смысл городить огород с "разнесением" процедур (как в примере) или лучше
Buff: array[0..pred(ENTRY_SIZE_OUTPUT_1024)] объявить внутри _FileRecordScanIO ?
P.S.
Не зависимо от ответа, хотелось бы понять "почему" :)


 
Игорь Шевченко ©   (2007-08-27 17:06) [1]

Не проще ли выделить потребный буфер в тот момент, когда станет известно значение GlobEntrySize, и пользоваться им ? Насколько я понимаю, оно не меняется в процессе работы ?


 
Riply ©   (2007-08-27 17:10) [2]

> [1] Игорь Шевченко ©   (27.08.07 17:06)
>Не проще ли выделить потребный буфер в тот момент, когда станет известно
>значение GlobEntrySize, и пользоваться им ?
Один и тот же буфер не получается использовать из-за рекурсии.
Для каждого вызова должна быть "своя личная область памяти"


 
Игорь Шевченко ©   (2007-08-27 17:16) [3]

я бы сделал иначе. я бы читал в одном месте, раз там буфер определяется по ходу выполнения программы, преобразовывал бы прочитанное в объект нужного мне формата, одинакового для разных размеров буфера, и то, что работает рекурсивно, вызывал бы с полученным объектом. Если что-то требуется прочитать, то опять же, читал в единственный буфер, преобразовывал бы и так далее, со всеми остановками до станции Можайск Смоленского направления.


 
Leonid Troyanovsky ©   (2007-08-27 17:50) [4]


> Riply ©   (27.08.07 16:41)  

> рекурсивная процедура FileRecordScanIO,
> которая вызывается очень много раз

Очень много может не поместиться в 1Мб - размер стека по умолчанию.
А еще, у локальной процедуры есть ограничение на размер локальных
переменных - 64K, если мне не изменяет склероз.

Т.е., здесь лучше GetMem - FreeMem.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2007-08-27 17:52) [5]


> Игорь Шевченко ©   (27.08.07 17:16) [3]

> бы и так далее, со всеми остановками до станции Можайск
> Смоленского направления.

Бываешь в тех краях?

--
Regards, LVT.


 
Игорь Шевченко ©   (2007-08-27 18:01) [6]

Leonid Troyanovsky ©   (27.08.07 17:52) [5]

В прошлом :) Голос на вокзале въелся в память.


 
Riply ©   (2007-08-27 21:15) [7]

>[3] Игорь Шевченко © (27.08.07 17:16)
>я бы сделал иначе...
Очень долго думала.
На настоящий момент, мне не удается представить себе реализацию предложенного.
Слишком много типов станций и развилок на Можайск Смоленском направлении
( взаимных ссылок и переплетений в коде :).
Я понимаю, что это плохо, но избавиться пока не получается :(
Сам "объект нужного мне формата" может оказаться не объектом, а списком
адресов, которые надо читать. Точно так же как и любой из его "подобъектов".
Иными словами: для парсинга почти любой из структур MFT
может потребоваться вызов процедуры чтения.

>[4] Leonid Troyanovsky © (27.08.07 17:50)
>Очень много может не поместиться в 1Мб - размер стека по умолчанию.
>А еще, у локальной процедуры есть ограничение на размер локальных
>переменных - 64K, если мне не изменяет склероз.
>Т.е., здесь лучше GetMem - FreeMem.
А если у нас вызовов то много, но рекурсия не очень "глубокая" ?
Рекомендации останутся такими же ?

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

В одной из веток форума (не смогла ее найти) читала, что при
рекурсии следует избегать блоков try/finally,
а слишком частый вызов GetMem - FreeMem ведет к фрагментации памяти.
В общем-то эти два утверждения и послужили поводом для создания данной ветки.


 
Leonid Troyanovsky ©   (2007-08-27 21:39) [8]


> Riply ©   (27.08.07 21:15) [7]


> А если у нас вызовов то много, но рекурсия не очень "глубокая"
> ?
> Рекомендации останутся такими же ?

Ну, если ты знаешь примерную глубину вызова, то можешь
прикинуть, какой стек может их принять, если размещать
буферы в нем.

> Надо работать с деревом, почти таким же как и файловое дерево
> для данного диска.
> Разница в том, что в нашем дереве для получения информации
> об одном узле(листе) может потребоваться не один рекурсивный
> вызов.

В наихудшем случае тебе потребуется файл из массива буферов
(на диске), проецируемый в память, и скользящий просмотр.

> а слишком частый вызов GetMem - FreeMem ведет к фрагментации
> памяти.

Если все размеры буферов известны, то можно выделить заведомо
большой блок VirtualAlloc и и собс-ручно нарезать его на массивы буферов.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2007-08-27 22:23) [9]


> Riply ©   (27.08.07 21:15) [7]

> а слишком частый вызов GetMem - FreeMem ведет к фрагментации

Если, скажем, все буферы одного размера, то фрагментации
не будет. Да и, в любом случае, сделать их одного размера
было б гораздо удобней.

Т.е., можно действовать так:
сначала пробывать размещать все в стеке,
если заходим слишком далеко, пытаемся решить
с помощью Get/FreeMem.
Если получается не слишком быстро, пытаемся собс-ручно
распределять большие блоки,
а если такие блоки не находятся -
боремся с фрагментацией адресного пространства
и т.д.

И, во-ще, о буферах какаого размера речь?

--
Regards, LVT.


 
Riply ©   (2007-08-28 03:32) [10]

>[9] Leonid Troyanovsky © (27.08.07 22:23)
>Если, скажем, все буферы одного размера, то фрагментации
>не будет. Да и, в любом случае, сделать их одного размера
>было б гораздо удобней.
В пределах одного диска они все одинакового размера.

>И, во-ще, о буферах какаого размера речь?
В любом случае размер не может превышать максимума из
(размера кластера и размера записи в MFT) плюс 32 байта.


 
Игорь Шевченко ©   (2007-08-28 09:29) [11]

А вот народ всякие lookaside-list"ы придумывает зачем-то...Не иначе с жиру бесится.


 
Leonid Troyanovsky ©   (2007-08-28 09:35) [12]


> Riply ©   (28.08.07 03:32) [10]

> В любом случае размер не может превышать максимума из
> (размера кластера и размера записи в MFT) плюс 32 байта.

Таким мне представляется оптимистичный подход:
VirtualAlloc блок размером BufSize * MaxLevel
Это будет двумерный массив [0..BufSize-1, 0..MaxLevel-1] of byte

Теперь, вместе с парметрами рекурсивной функции передаем
var Level: Longint, который будет использоваться  для выбора буфера.

Т.е., при входе в функцию - inc(Level), при выходе - dec.

Пессемистичный подход - Get/FreeMem на каждом уровне.

Промежуточные подходы даже неохота обсуждать,
возможно, что это набор блоков разного размера,
данные о которых также размещаются в стеке.

--
Regards, LVT.


 
Riply ©   (2007-08-28 15:37) [13]

>[12] Leonid Troyanovsky ©   (28.08.07 09:35)
Спасибо.
Наверное, попробую использовать "оптимистичный подход".

>[11] Игорь Шевченко ©   (28.08.07 09:29)
>А вот народ всякие lookaside-list"ы придумывает зачем-то...Не иначе с жиру бесится.
Не знала, что такие существуют.
Почитала общее описание их предназначения. Все так красиво выглядит :)


 
GrayFace ©   (2007-09-16 13:07) [14]

Riply ©   (27.08.07 17:10) [2]
Один и тот же буфер не получается использовать из-за рекурсии.
Для каждого вызова должна быть "своя личная область памяти"

_FileRecordParsingIO мыжет вызвать FileRecordScanIO?

Leonid Troyanovsky ©   (27.08.07 17:50) [4]
А еще, у локальной процедуры есть ограничение на размер локальных
переменных - 64K, если мне не изменяет склероз.

Ограниечние компиллятора?

Riply ©   (27.08.07 21:15) [7]
В одной из веток форума (не смогла ее найти) читала, что при
рекурсии следует избегать блоков try/finally

Скорее всего, речь об экономии места в стеке.


 
Riply ©   (2007-09-16 18:17) [15]

> [14] GrayFace ©   (16.09.07 13:07)
> _FileRecordParsingIO мыжет вызвать FileRecordScanIO?
Может вызывать, если ему это понадобиться :)


 
Leonid Troyanovsky ©   (2007-09-20 15:22) [16]


> GrayFace ©   (16.09.07 13:07) [14]

> переменных - 64K, если мне не изменяет склероз.
> Ограниечние компиллятора?

Только, вот, не помню какого :)

C ограничением я погнал, sorry.

--
Regards, LVT.



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

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

Наверх





Память: 0.5 MB
Время: 0.056 c
15-1189593227
de.
2007-09-12 14:33
2007.10.14
El-lib


2-1190207865
AigizK
2007-09-19 17:17
2007.10.14
Как подключить файл


15-1189595935
S@D
2007-09-12 15:18
2007.10.14
Помогите ПЛИЗ!


15-1189805822
searching the true :)
2007-09-15 01:37
2007.10.14
отчего :)


15-1189596497
FreeTT
2007-09-12 15:28
2007.10.14
Добавление группы в TRZBarGroup





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