Низкое использование ОЗУ + частое выделение/освобождение приводит к тому, что Linux заменяет другие программы

программа, над которой я сейчас работаю, обрабатывает большой объем данных (> 32 ГБ). Однако из-за «конвейерной обработки» в каждый момент времени в основной памяти присутствует максимум около 600 МБ (я проверил, это работает, как и планировалось).

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

На моем компьютере установлено 4 ГБ оперативной памяти, и пока моя программа активна, она никогда не превышает 2 ГБ.

Моя программа выделяет/освобождает динамическую память только двух разных размеров. Куски по 32 и 64 МБ. Он написан на C++, и я использую new и delete. Должен ли Linux быть недостаточно умным, чтобы повторно использовать эти блоки после того, как я их освободил, и оставить остальную память нетронутой?

Почему Linux выкидывает мои вещи из памяти? Это какой-то другой эффект, который я не учел? Могу ли я обойти эту проблему без написания собственной системы управления памятью?


person Lazarus535    schedule 16.03.2015    source источник
comment
Если вы выполняете файловый ввод-вывод, ОС попытается кэшировать данные вашего файла, а старые данные программы менее важны для сохранения в памяти, что, вероятно, вы и видите, а не для выделения памяти.   -  person Mats Petersson    schedule 17.03.2015
comment
Если вы не перегрузили new и delete, чтобы пропустить реализацию диспетчера кучи вашего компилятора, именно диспетчер кучи вашего компилятора контролирует внутреннюю работу того, как ваше приложение взаимодействует с ОС w.r.t. управление памятью, а не напрямую new и delete.   -  person PaulMcKenzie    schedule 17.03.2015
comment
Спасибо вам обоим! @Mats Petersson: Да, я много выполняю файловый ввод-вывод с жесткого диска. Так что пользовательский менеджер памяти (повторное использование блоков) не поможет? Могу ли я отключить это поведение, сказав Linux, что он не должен хранить фрагменты прочитанных файлов в памяти?   -  person Lazarus535    schedule 17.03.2015
comment
@PaulMcKenzie: я бы использовал слово new и delete библиотеки времени выполнения C ++, а не компилятора. И, скорее всего, библиотека времени выполнения будет повторно использовать блоки — иначе вы увидите увеличение использования памяти!   -  person Mats Petersson    schedule 17.03.2015
comment
@ Lazarus535: в Linux можно настроить ряд настраиваемых параметров. Я не уверен, какие именно из них вы должны настроить, чтобы улучшить это, вы, вероятно, повлияете на ЧТО-ТО еще (например, Firefox также будет медленнее), так что это не просто изменение параметра X на 28 вместо 42. Вот что я только что нашел это погуглить для настроек кеша, хотя вы пытаетесь добиться ПРОТИВОПОЛОЖНОСТИ того, что вы делаете, он показывает, что представляют собой некоторые настройки, со ссылками на объяснение. unix.stackexchange.com/questions/30286/   -  person Mats Petersson    schedule 17.03.2015
comment
Я предлагаю вам начать с команды vmstat 1, чтобы подтвердить свои догадки. Обратите внимание на столбцы si и so, связанные с чтением/записью подкачки.   -  person myaut    schedule 17.03.2015
comment
Похоже, кому-то нужно узнать о posix_fadvise.   -  person David Schwartz    schedule 17.03.2015


Ответы (2)


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

Вы можете сделать это напрямую с помощью linux API, но я предлагаю вам использовать такую ​​библиотеку, как Boost ASIO. Если ваше программное обеспечение связано с вводом-выводом, вам следует дополнительно использовать асинхронный ввод-вывод для повышения производительности.

person Sophit    schedule 16.03.2015
comment
Без кэширования ваше программное обеспечение может работать быстрее. Он также может работать медленнее. - person Mooing Duck; 17.03.2015
comment
Вы как будто даже не читали, что я написал. - person Sophit; 17.03.2015
comment
Нет, вы написали, но только в том случае, если вам не нужно потом перезагружать те же данные. Без кэширования файлов он также может работать медленнее во многих других распространенных обстоятельствах. - person Mooing Duck; 17.03.2015
comment
Он обрабатывает › 32 ГБ данных последовательно, используя 4 ГБ оперативной памяти. Кэширование будет быстрее, чем без кэширования, в том экстраординарном случае, когда он обрабатывает каждый файл по мере его записи на диск, и только если он может обрабатывать файлы так же быстро, как они записываются. Если бы это было правдой, я бы все еще сомневался, будет ли это верно для будущих версий программного обеспечения. - person Sophit; 17.03.2015
comment
Я использую асинхронный ввод-вывод (собственная реализация, но я ею доволен :-D). В этом проекте я стараюсь придерживаться стандартной библиотеки из-за более поздних применений, где ускорение может быть недоступно. Я использовал boost:: asio для другого проекта (в основном для сетей). Итак, boost::asio может предоставить независимые от платформы флаги для отключения кэширования независимым от платформы способом (важно)? В таком случае буду рассматривать переход. Спасибо. - person Lazarus535; 17.03.2015
comment
›32 ГБ относится к входному файлу. Так что только чтение. Наверное, надо было это упомянуть. Записанный файл (результат) довольно маленький (менее 5 МБ). - person Lazarus535; 17.03.2015
comment
Я тоже всегда использовал свои собственные библиотеки. Я предполагаю, что asio имеет эту функцию, но я могу ошибаться. Если вы предпочитаете, используйте aio.h непосредственно в Linux, чтобы получить небуферизованное асинхронное чтение. - person Sophit; 17.03.2015
comment
Позже программа станет мультиплатформенной. Так что я не могу делать только Linux. И я не хочу кодировать специфичный для платформы код :-D. посмотрю буст...посмотрю. - person Lazarus535; 17.03.2015
comment
Возможно, я ошибался, судя по документации ASIO, которую я только что просмотрел, а также этот вопрос. Мне жаль, что у меня нет другой библиотеки, чтобы предложить. В противном случае вы застрянете в написании реализации для каждой платформы. - person Sophit; 17.03.2015

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

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

person David Schwartz    schedule 17.03.2015
comment
В какой-то момент я использовал файлы с отображением памяти. Но если есть более одного файла для параллельного чтения (один индекс из одного файла, за которым следует один индекс из другого файла), linux будет читать только 4 КБ страниц за раз для каждого файла, что в основном снижает производительность ввода-вывода (по крайней мере, для меня так и было). Я использовал файл отображения ускорения в более ранней версии. К сожалению, он НЕ выставляет флаг madvice (или аналогичный независимый от платформы). И, как уже упоминалось: НЕТ специфичного для платформы кода. В остальном хороший ответ. Спасибо. - person Lazarus535; 17.03.2015