Мне нравится разрабатывать алгоритмы с использованием STL, однако у меня есть эта повторяющаяся проблема, когда мои наборы данных слишком велики для кучи.
Я искал замену для контейнеров и алгоритмов STL с дисковой поддержкой, то есть структур данных, хранящихся на диске, а не в куче.
Друг недавно указал мне на stxxl. Прежде чем я слишком увлекся этим ... Доступны ли какие-либо другие замены STL с дисковой поддержкой, которые мне следует рассмотреть?
ПРИМЕЧАНИЕ: меня не интересуют постоянные или встроенные базы данных. Пожалуйста, не упоминайте boost :: serialization, POST ++, библиотеку реляционных шаблонов, Berkeley DB, sqlite и т. д. Я знаю об этих проектах и использую их, когда они подходят для моих целей.
ОБНОВЛЕНИЕ: несколько человек упомянули файлы отображения памяти и использование настраиваемого распределителя, хорошие предложения, кстати, но я бы указал им на обсуждение здесь, где Дэвид Абрахам предполагает, что для контейнеров с дисковой поддержкой потребуются специальные итераторы. Это означает, что подход настраиваемого распределителя вряд ли сработает.
@Donal Он может зарезервировать неправильный объем памяти.





Я не очень разбираюсь в этом предмете, но возможно ли записать STL-подобный интерфейс в файл с отображением памяти?
edit: этот подход может быть подходящим, если вы пытаетесь получить доступ к определенной части огромного файла. Если вы пытаетесь что-то сделать со всем файлом, вы, вероятно, сгенерируете огромное количество ошибок страниц при чтении некэшированных частей файла.
Я подумал о том, чтобы сделать это ... но я бы не стал писать это сам, если что-то полезное уже было сделано.
Я понимаю, что не хочу изобретать велосипед. Я не знаком с библиотекой, которая делает это; надеюсь, кто-то может порекомендовать один.
Я считаю, что Boost.Interprocess можно использовать для записи в файл с отображением памяти. Хотя на самом деле не пробовал.
Если (когда вы пишете) вас не интересует постоянство, самым простым решением было бы увеличить размер кучи и использовать средства виртуальной памяти вашей операционной системы. Часть кучи, которая не умещается в физической памяти вашего компьютера, в конечном итоге будет выгружена на диск, что даст вам именно то, что вы хотите: обычный STL-доступ к данным, часто хранящимся на диске. Операционная система позаботится о кэшировании наиболее часто используемых страниц в физической памяти и удалении на диск тех, которые вы не используете часто. Ваш код останется прежним, и вы сможете повысить его производительность, просто добавив больше физической памяти.
Чтобы увеличить размер кучи, проверьте параметры вашей операционной системы, такие как ulimit (1) в системах Unix и Свойства системы - Дополнительно - Производительность - Дополнительно - Виртуальная память в Windows XP. Если вы достигли 32-разрядного предела в 4 ГБ, подумайте о переходе на 64-разрядную архитектуру или компиляции вашей программы для 64-разрядной версии.
Я опытный системный администратор, я рассмотрел предложенный вами подход. У меня есть машина amd64 под управлением unix. Я не могу позволить себе добавить больше физической памяти. Мое пространство подкачки составляет 2 ГБ, мой набор данных - 42 ГБ, мой жесткий диск - 1 ТБ ...
Итак, как насчет увеличения пространства подкачки?
Конечно, я подумал о том, чтобы перестроить свой сервер под этот проект. Однако это не специализированное оборудование, а машина, используемая для общих исследований. Помимо этого, в конечном итоге соавторам также потребуется запускать код, и я не думаю, что требование перестраивать свои машины сработает.
Мне никогда не приходилось делать ничего подобного, но, возможно, можно было бы сделать то, что вы хотите, написав собственный распределитель, который использует файлы с отображением памяти для резервного копирования ваших данных.
См. Документацию об их простой в использовании реализации файлов с отображением памяти в boost :: interprocesses, в эта статья доктора Доббса для подробного обсуждения написания распределителей и в этот столбец программного обеспечения IEEE для описания проблемы и пример кода.
Я знаю статью DDJ, хорошая статья. Тем не менее, было обсуждение списка рассылки boost между Terpstra, Kuehl и Abraham, в котором предполагалось, что для работы со структурами данных на диске потребуются специальные итераторы ... что исключает подход настраиваемого распределителя.
Я реализовал нечто очень похожее. Реализация итераторов является наиболее сложной задачей. Я использовал boost :: iterator_facade для реализации итераторов. Используя boost::iterator_facade, вы можете легко адаптироваться любой кэшированной на структуры данных на диске, чтобы иметь интерфейс контейнера STL.
Я использую Boost, но iterator_facade для меня в новинку. Мне нужно взглянуть на это, спасибо, что поделились.
Хотите поделиться реализацией?
К сожалению, я не могу поделиться этим кодом. Однако, если у вас есть какие-либо вопросы, я буду более чем счастлив помочь.
Если ваши наборы данных слишком велики для кучи, вам следует подумать, правильна ли архитектура вашей системы (например, нужно ли переходить на 64-битную систему; сейчас это более распространено, чем когда был задан вопрос). Вы также должны подумать, является ли STL правильным подходом; он может делать предположения о размере набора данных, которые вам не подходят.