Производительность отображаемых в память файлов - управление памятью при работе с большими наборами данных - PullRequest
1 голос
/ 29 октября 2010

У меня есть ситуация, когда мне нужно работать с множеством (15-30) больших (несколько сотен мегабайт) структур данных.Они не вписываются в память одновременно.Что еще хуже, алгоритмы, работающие на них, работают во всех этих структурах, то есть не в первой, а в другой и т. Д. Мне нужно сделать это как можно быстрее.

Так что я решил выделить памятьна диске, в файлах, которые в основном являются прямыми двоичными представлениями данных, когда они загружаются в память, и используют отображенные в памяти файлы для доступа к данным.Я использую mmap 'views', например, 50 мегабайт (50 МБ файлов загружаются в память за раз), поэтому, когда у меня есть 15 наборов данных, мой процесс использует 750 МБ памяти для данных.Первоначально это было нормально (для тестирования), когда у меня есть больше данных, я уменьшаю 50 Мб за счет некоторой скорости.

Однако эта эвристика пока жестко запрограммирована (я знаю размер данныхустановить я буду тестировать с).«В дикой природе», мое программное обеспечение должно быть в состоянии определить «правильный» объем памяти, выделяемый для максимизации производительности.Я мог бы сказать: «Я буду использовать 500 МБ памяти», а затем разделить 500 на количество структур данных, чтобы получить размер представления mmap.Я обнаружил, что при попытке установить слишком высокое «целевое использование памяти» перегрузка диска менеджера виртуальной памяти (почти) заблокирует компьютер и сделает его непригодным для использования до завершения обработки.Этого следует избегать в моем «производственном» решении.

Итак, мои вопросы, все несколько разные подходы к проблеме:

  • Каков «лучший» размер целидля одного процесса?Должен ли я просто попытаться максимально увеличить 2 ГБ, которые у меня есть (при условии, что 32-разрядная версия Win XP и выше, на данный момент не / 3 ГБ), или попытаться уменьшить размер процесса, чтобы мое программное обеспечение не перегружало машину?Когда на моей машине открыто 2 Visual Studio, Outlook и Firefox, они легко используют 1/2 ГБ виртуальной памяти - если я позволю моему программному обеспечению использовать 2 ГБ виртуальной памяти, подкачка сильно замедлит работу машины.Но тогда как сделать я определяю «лучший» размер процесса.

  • Что я могу сделать, чтобы контролировать производительность машины при работе с отображенными в память файлами?Мое приложение выполняет довольно простые числовые операции с данными, что в основном означает, что оно очень быстро копирует сотни мегабайт данных, в результате чего целые файлы с отображением в памяти (несколько гигабайт) загружаются в память и снова очень быстро выгружаются, сноваи снова (подумайте о моделировании в стиле Монте-Карло).

  • Есть ли вероятность, что использование файлов с отображением в памяти и использование только fseek / fgets будет быстрее или менее навязчивым, чем использование памятисопоставленные файлы?

  • Любые статьи, статьи или книги, которые я могу прочитать об этом?Либо с решениями в стиле «поваренной книги», либо с фундаментальными концепциями.

Спасибо.

Ответы [ 4 ]

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

Я, вероятно, не использовал бы отображенный в памяти файл для этого приложения.Файлы с отображением в памяти работают лучше всего, когда у вас большое виртуальное адресное пространство (по крайней мере, относительно размера данных, которые вы обрабатываете).Вы отображаете весь файл и позволяете ОС решать, какие части остаются резидентными.

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

Один из способов, с помощью которого сегментированные вручную отображенные в память файлы могут выиграть, - это если у вас есть редкие чтения: если вы только касаетесь, скажем, 10% от заданного файла.В этом случае отображение памяти означает, что ОС будет читать только те страницы, к которым обращаются, тогда как явное чтение загрузит весь файл.

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

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

Я думаю, что это хорошее место, чтобы попробовать расширения оконного адреса: http://msdn.microsoft.com/en-us/library/aa366527(v=VS.85).aspx

Это позволит использовать более 4 ГБ памяти, предоставляя скользящее окно. Недостатком является то, что не все версии окон имеют его.

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

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

Начните консервативно низко. Если это ниже вашего «слишком чертовски медленного» порога, немного увеличьте размер для следующего файла. сделать это итеративно. Когда вы превышаете пороговое значение, медленно уменьшайте размер итеративно.

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

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

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

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

Если последовательный доступ к данным широко разбросан по вашему файлу, вам может быть лучше использовать fseek и fread для доступа к данным, поскольку это даст вам более точный контроль того, какие данные записываются в память при *. 1007 *

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

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