40 миллионов страниц ошибок.Как это исправить? - PullRequest
4 голосов
/ 15 октября 2010

У меня есть приложение, которое загружает 170 файлов (скажем, текстовых файлов) с диска в отдельные объекты и постоянно хранится в памяти.Память выделяется один раз, когда я загружаю эти файлы с диска.Таким образом, нет фрагментации памяти.Я также использую FastMM, чтобы убедиться, что мои приложения никогда не теряют память.

Приложение сравнивает все эти файлы друг с другом, чтобы найти сходства.Слишком упрощенно можно сказать, что мы сравниваем текстовые строки, но алгоритм более сложный, так как я должен допустить некоторые различия между строками.Каждый файл составляет около 300 КБ.Загруженный в память (объект, который его удерживает) занимает около 0,4 МБ ОЗУ.Итак, запущенное приложение занимает около 60 МБ или ОЗУ (рабочий набор).Обрабатывает данные около 15 минут.Дело в том, что он генерирует более 40 миллионов ошибок страниц.

Почему?У меня около 2 ГБ свободной оперативной памяти.Из того, что я знаю, страница сбоев идет медленно.Насколько они тормозят мою программу?Как я могу оптимизировать программу, чтобы уменьшить количество ошибок на странице?Я думаю, это как-то связано с локальностью данных.Кто-нибудь знает некоторые примеры алгоритмов для этого (Delphi)?

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


Delphi 7, Win 7 32-битная, ОЗУ 4 ГБ (3 ГБ видимые, 2 ГБ свободные).

Ответы [ 3 ]

3 голосов
/ 15 октября 2010

Предостережение - я только решаю проблему с ошибкой страницы.

Не могу быть уверен, но рассматривали ли вы возможность использования файлов с отображенной памятью? Таким образом, окна будут использовать сами файлы как файл подкачки (а не как основной файл подкачки pagrefile.sys). Если файлы доступны только для чтения, то число сбоев страниц теоретически должно уменьшиться, так как страницы не должны будут записываться на диск через файл подкачки, поскольку Windows просто загружает данные из самого файла по мере необходимости.

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

Обратите внимание, что файлы Memory Mapped - это то, как Windows загружает .dll и .exes среди прочего. Я использовал их для сканирования файлов размером в гигабайты без ограничения памяти (в те дни у нас были МБ, а не ГБ ОЗУ).

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

1 голос
/ 15 октября 2010

На моем компьютере сообщается, что большинство ошибок страниц приходится на студию разработчика, которая, как сообщается, имеет 4M ошибок страниц после 30+ минут общего времени процессора. Вы получаете в 10 раз больше, в два раза. И памяти в моей системе мало. Так что ошибки 40M кажутся большими.

Может быть , может быть , если у вас утечка памяти.

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

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

0 голосов
/ 15 октября 2010

Используете ли вы экспоненциальную систему изменения размера?

Если вы увеличиваете блок памяти слишком маленькими шагами во время загрузки, он может постоянно запрашивать большие блоки из системы, копировать данные и затем освобождать старый блок (при условии, что fastmm (de) выделяет оченьбольшие блоки непосредственно из ОС).

Может быть, это как-то вызывает цикл, в котором ОС освобождает память из процесса вашего приложения, а затем добавляет ее снова, вызывая сбои страниц при первой записи.

Такжеизбегайте методов Tstringlist.load * для очень больших файлов, IIRC занимают вдвое больше места.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...