40 миллионов страниц ошибок. Как это исправить?

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

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

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

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


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

3 ответа

Решение

Предостережение - я только обращаюсь к страничной проблеме.

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

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

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

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

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

Это может быть просто утечка памяти.

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

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

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

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

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

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

Другие вопросы по тегам