![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Хранение данных больших размеров [D6, D7, WinXP]
olorint © (2005-07-23 14:33:00)В программе необходимо хранить данные больших размеров. Точнее массив записей размером в 16 млн. ячеек. Типы в записе: byte и word. Массив в памяти занимает 400mb. Думал записать его в файл и работать ч/з файл, но ч/з некоторое время программа выдает ошибку переполнение стека. Глобальных переменных в программе нет. Все локальные освобождаются после использования.
Как ускорить работу Delphi с такими данными.
Slym (2005-07-27 12:02:00) [1]MemoryMappedFile - компромис файла-памяти
olorint (2005-07-27 01:27:00) [2]Народ, большое всем спасибо за советы.
Конечно все проблемы можно решить добавлением новой планки памяти, но это не интересно.
Так что результат такой:динамическое выделение памяти не дает особых результатов. А дальше как ни странно банальные истины, которые каждый знает но мало ими пользуется (по себе сужу).
Насчет переполнения стека:
можно использовать и динамическую память, но сначала стоило проверить возможные(теоретические значения переменных), и изменить тип. Так например Integer сменил на Word а это уже 2 байта. и так далее по мелочам.
Практические испытания показали на моем компьютере, размер переменных (локальных), приходящихся на одну процедуру не может превышать 25 Мб. Можно перевести переменные в динамические или объявить их глобальными(дико, но работает), либо использовать файл для их хранения на диске.
Сравнение времени для обработки массива на 29 млн записей формата 3 поля Word 3 поля Byte, показало преимущество ипользования файла а не динамической памяти. Время 40-60 сек.
Спасибо всем за помощь, некоторые идеи помогли решить дальнейшие проблемы.
Вопрос закрыт.
palva (2005-07-23 22:24:00) [3]> приходится при любой операции перелопачивать весь массив те конкретный загруз всех страниц в память
Тяжелый случай. Может быть можно переупорядочить массив так, чтобы перелопачивание шло более-менее последовательно? Скажем, если массив содержит представление большого графа, то можно попробовать упорядочить вершины.
В любом случае надо ставить на машину как можно большую память.
begin...end (2005-07-23 21:31:00) [4]> tesseract © (23.07.05 21:16) [14]
> Массив сам по себе размешается в куче, а не в стеке
Вас обманули. Вот простой пример:
function F: Integer;
var
A: array [1..5] of Integer; <-- Статический массив, являющийся локальной переменной
begin
Result := A[1]
end.
Вызываем эту функцию в коде и смотрим в окно CPU. Функция начинается вот с чего:
83C4EC add esp,-$14
Это -- уменьшение указателя вершины стека на $14 = 20, т.е. выделение в СТЕКЕ памяти под массив A размером 20 байт.
> try .. except реально вставляется перед любой
> операцией с не константами кроме операций с
> указателями.
Ну-ну.
tesseract (2005-07-23 21:16:00) [5]>>to begin..end
Массив сам по себе размешается в куче, а не в стеке - стек совершенно другой тип данных SteckOverflow- показатель того что система не может сохранить все данные текущей функции перед вызовом другой. Т.Е. Какое это отношение имеет к данным?
try .. except реально вставляется перед любой операцией с не константами кроме операций с указателями. Т.Е реально можно получить либо SteсkOverflow либо дельфи выдаст AccessViolation.
tesseract (2005-07-23 21:11:00) [6]to palva >>> Как правило в данном случае приходится при любойолперации перелопачивать весь массив те конкретный загруз всех страниц в память. ТЕ надо не грузить его весь в память а обходиться малыми средствами.
to olorint>> Некоторый выход все данные с диска читать необязательно record имеет устаканенный формат? тогда размер его фиксирован, следовательно можно сбросить данные на диск и искать нужные данные Read() с установленным размером блока в Reset в размер записи.
begin...end (2005-07-23 21:01:00) [7]> tesseract © (23.07.05 20:51) [10]
> И ещё перед каждой операцией с любой переменной
> вставляется скрытый try .. except.
Вставки чего-то перед каждой операцией с любой переменной я не замечал. Кстати, Вы это к чему? Вы спросили, какая связь между массивом и переполнением стека. Я ответил.
palva (2005-07-23 20:58:00) [8]Можно работать, разместив массив в памяти, но тогда скорее всего будет подкачка памяти с диска. Алгоритм подкачки анализирует статистику обращений к массиву и располагает малоиспользуемые в настоящий момент фрагменты на диске. Как правило у программиста имеется возможность, зная алгоритм задачи, организовать подкачку самому более эффективно. Кроме того он может изменить сам алгоритм задачи (скажем обрабатывать массив частями) с тем чтобы подкачку (ручную) можно было легче организовать.
Такие соображения...
tesseract (2005-07-23 20:51:00) [9]>>Притом, что локальные переменные размещаются в стеке.
И ещё перед каждой операцией с любой переменной вставляется скрытый try .. except.
>> Всё, что он кушает, он кушает из кучи, а не из стека.
системный стек вызова и данная ошибка, как правило, сильно взаимосвязаны.
Anatoly Podgoretsky (2005-07-23 20:46:00) [10]olorint © (23.07.05 20:10) [4]
Ты не волнуйся, но у тебя в программе ошибка.
begin...end (2005-07-23 20:43:00) [11]> tesseract © (23.07.05 20:40) [7]
> причём здесь массив и SteckOverflow
Притом, что локальные переменные размещаются в стеке.
> а тем более динамический массив который вообще памяти
> кушает тремя ложками
Всё, что он кушает, он кушает из кучи, а не из стека.
tesseract (2005-07-23 20:40:00) [12]Процесс в Windows Nt/XP может адресовать до 4GB виртуальной памяти.
>>>Насчет 32 Мб не согласен. Массив записанный в файл занимает 400 Мб. Тоже самое и при хранении его в памяти.
А оно тебе надо ? Массив в памяти запросто займёт больше места. Как правило они так и делают - за счёт служебной информации и тд и тп.
>> byte и word это если только у тебя Packed Record. Компилер дельфей оптимизируй код под пни выполняет 32-битное выравнивание - все целочисленные числа приводяться под int32.
>> Ты такой массив в стеке хранишь?
ЁЁЁЁЁЁЁЁЁЁ причём здесь массив и SteckOverflow ?????? а тем более динамический массив который вообще памяти кушает тремя ложками.
StackOverflow связан с вызовами функций - скорее всего проблема в рекурсивном вызове некотрых функций.
>> ячеек. Использовать БД нельзя, т.к. по ТЗ не предусмотрено.
А ты предусмотри.
begin...end (2005-07-23 20:37:00) [13]> Anatoly Podgoretsky © (23.07.05 15:10) [3]
> vrem (23.07.05 20:32) [5]
В [0] не указано количество полей типа Byte или Word. Возможно также, что это переопределённые типы.
vrem (2005-07-23 20:32:00) [14]16 млн *(1+2) = 48 млн байт = 45,776 мегабайт
olorint (2005-07-23 20:10:00) [15]массив - используется как хранилище данных, т.е. при начале работы программы он инициализируется на основе исходных данных, а потом происходит чтение ячеек. Использовать БД нельзя, т.к. по ТЗ не предусмотрено.
To Podgoretsky
Насчет 32 Мб не согласен. Массив записанный в файл занимает 400 Мб. Тоже самое и при хранении его в памяти.
evvcom
Насчет динамического не пробовал. Сейчас посмотрим.
Anatoly Podgoretsky (2005-07-23 15:10:00) [16]olorint © (23.07.05 14:33)
Массив в памяти занимает 16/32 мегабайта
palva (2005-07-23 15:06:00) [17]1. По-моему надо работать через файл.
2. >Как ускорить работу Delphi с такими данными
Во-первых, нужно устранить ошибку, которая приводит к переполнению стека. А как ускорить - это во многом зависит от того, какая работа с данными требуется. Возможно, получится ускорение от перехода с файла на базу данных, например, Access
evvcom (2005-07-23 14:59:00) [18]
> но ч/з некоторое время программа выдает ошибку переполнение
> стека. Все локальные
> освобождаются после использования.
Ты такой массив в стеке хранишь? Убери. Используй динамический массив, и стек будет в порядке.