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

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

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

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

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

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

1

Решение

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

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

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

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

5

Другие решения

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

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

1

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

0

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

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

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

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

0

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

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

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

0