Использование памяти в программе на C++

Я написал программу, которая должна обрабатывать очень большие данные со следующими библиотеками:

  • вектор
  • повышение:: unordered_map
  • повышение:: unordered_multimap

Итак, у меня проблемы с памятью (программа использует LOT), и я подумал, может быть, я смогу заменить эти библиотеки (на то, что уже существует или мои собственные реализации):

Итак, три вопроса:

  • Сколько памяти я бы сэкономил, если бы я заменил вектор массивом C? Стоит ли оно того?
  • Может кто-нибудь объяснить, как память используется в boost:: unordered_map и boost:: unordered_multimap в текущей реализации? Как то, что хранится для достижения их производительности.
  • Можете ли вы порекомендовать мне некоторые библиотеки, которые превосходят boost:: unordered_map и boost:: unordered_multimap в использовании памяти (но не слишком ли это медленно)?

5 ответов

Решение

Я закончил, изменив boost::unordered_multimap за std::unordered_map из vector,

boost::unordered_multimap потребляет более чем в два раза больше памяти, std::unordered_map из vector из-за дополнительных указателей, которые он сохраняет (по крайней мере, один дополнительный указатель на элемент) и того факта, что он хранит ключ и значение каждого элемента, в то время как unordered_map из vector хранит ключ только один раз для вектора, который содержит все сталкивающиеся элементы.

В моем конкретном случае я пытался хранить около 4000 000 целых чисел, потребляя около 15 ГБ памяти в идеальном случае. Используя мультикарту, я получаю более 40 ГБ, а при использовании карты я использую около 15 ГБ (немного больше из-за указателей и других структур, но их размер, если это презренно).

std::vector эффективна ли память Я не знаю о картах буста, но люди из Boost обычно знают, что делают, я сомневаюсь, что вы сэкономите много памяти, создав собственные варианты.

Вы можете сделать несколько других вещей, чтобы помочь с проблемами памяти:

  1. Компилировать в 64 бит. Недостаточно памяти в 64-битном процессе очень сложно.
  2. Вам не хватит памяти, но память может быть выгружена. Вместо этого вы должны увидеть, нужно ли вам загружать все в память одновременно, возможно, вы можете работать с порциями данных за раз.
  3. Дополнительным преимуществом является то, что одновременная работа с фрагментом данных позволяет параллельно выполнять код.

Сегодня, когда память настолько дешева, что выделение 10 ГБ ОЗУ очень просто, я думаю, что ваши узкие места будут в обработке данных, а не в распределении данных.

Эти две статьи объясняют структуры данных, лежащие в основе некоторых распространенных реализаций неупорядоченных ассоциативных контейнеров:

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

Если у вас есть только один набор данных и несколько способов доступа к ним, вы можете попробовать использовать boost::multi_index вот документация

std::vector - это в основном непрерывный массив, плюс несколько байтов служебных данных. Единственный способ улучшить работу с вектором - использовать меньший тип элементов. Можете ли вы хранить короткий int вместо обычного int? Если это так, вы можете сократить векторную память наполовину.

Возможно, вы используете эти контейнеры для хранения указателей на множество объектов в куче? Если это так, у вас может быть много потерянного пространства в куче, которое может быть сохранено путем написания пользовательских распределителей или путем полного устранения указателя на элемент кучи и сохранения типа значения в контейнере.

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

Оперативная память в 2014 году дешевая. Достаточно просто построить процессоры Intel x86-64 с 64–256 ГБ оперативной памяти и твердотельным диском для быстрой замены, если текущая версия не подходит для проекта. Надеюсь, это не коммерческое настольное приложение, которое мы обсуждаем.:)

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