У меня есть приложение Visual Studio 2008 C++, где я использую настраиваемый распределитель для стандартных контейнеров, так что их память поступает из файла с отображением памяти, а не из кучи. Этот распределитель используются для 4-х различных случаев использования:предложения по улучшению реализации алгоритма распределителя
- 104-байтовых структуры фиксированного размера
std::vector< SomeType, MyAllocator<SomeType> > foo;
- 200-байтового фиксированного размером структура
- 304-байтовых структуры фиксированного размера
- н-байтовых строк
std::basic_string< char, std::char_traits<char>, MyAllocator<char> > strn;
Мне нужно уметь распределять примерно 32 МБ для каждого из них.
Распределитель отслеживает использование памяти с помощью указателей std::map
указателей на размер выделения. typedef std::map< void*, size_t > SuperBlock;
Каждый SuperBlock представляет собой 4 МБ памяти.
Существует std::vector<SuperBlock>
из них, если один SuperBlock недостаточно.
Алгоритм, используемый для распределителем выглядит следующим образом:
- Для каждого SuperBlock: Есть ли место в конце SuperBlock? поставьте там распределение. (быстро)
- Если нет, выполните поиск в пределах каждого SuperBlock для свободного пространства достаточного размера и разместите выделение там. (медленно)
- По-прежнему ничего? выделите еще один SuperBlock и поставьте выделение в начале нового SuperBlock.
К сожалению, шаг 2 через некоторое время может стать ОЧЕНЬ медленным. По мере создания копий объектов и уничтожения временных переменных я получаю много фрагментации. Это вызывает много глубоких поисков в структуре памяти. Фрагментация возникает, так как у меня ограниченный объем памяти для работы (см. Примечание ниже).
Может ли кто-нибудь предложить усовершенствования этого алгоритма, что ускорит процесс? Нужно ли мне два отдельных алгоритма (1 для распределений фиксированного размера и один для распределителя строк)?
Примечание: Для тех, кому нужна причина: я использую этот алгоритм в Windows Mobile, где ограничение на процессорное пространство составляет 32 МБ. Таким образом, обычный std::allocator
не отрежет. Мне нужно поставить выделение в 1 ГБ большой области памяти, чтобы иметь достаточно места, и это то, что это делает.
Хорошая идея объединить фиксированные и переменные размеры. Я только что реализовал это, и это очень быстро. Спасибо. – PaulH
Вы должны прочитать Маттиу М. ответ, он намного более полный и неплохой и справляется с большим количеством проблем, с которыми вы столкнетесь, если вы развернете свои собственные распределители. –