У меня есть приложение Visual Studio 2008 C++, в котором я использую настраиваемый распределитель для стандартных контейнеров, так что их память поступает из файла с отображением памяти, а не из кучи. Этот распределитель используется для 4 различных вариантов использования:
- 104-байтовая структура фиксированного размера
std::vector< SomeType, MyAllocator< SomeType > > foo;
- 200-байтовая структура фиксированного размера
- 304-байтовая структура фиксированного размера
- n-байтовые строки
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 недостаточно места.
Алгоритм, используемый для распределителя, выглядит следующим образом:
- Для каждого суперблока: есть ли место в конце суперблока? поместите выделение туда. (быстрый)
- Если нет, найдите в каждом суперблоке пустое пространство достаточного размера и поместите выделение туда. (медленный)
- Еще ничего? выделить еще один суперблок и поместить выделение в начало нового суперблока.
К сожалению, через некоторое время шаг 2 может стать ОЧЕНЬ медленным. Когда создаются копии объектов и уничтожаются временные переменные, я получаю большую фрагментацию. Это вызывает много глубоких поисков в структуре памяти. Проблема фрагментации, так как у меня ограниченный объем памяти для работы (см. примечание ниже).
Может ли кто-нибудь предложить улучшения этого алгоритма, которые ускорили бы процесс? Нужны ли мне два отдельных алгоритма (один для выделения фиксированного размера и один для распределителя строк)?
Примечание. Для тех, кому нужна причина: я использую этот алгоритм в Windows Mobile, где ограничение слота процесса для кучи составляет 32 МБ. Так что обычный std::allocator
не подойдет. Мне нужно разместить выделения в большой области памяти объемом 1 ГБ, чтобы было достаточно места, и это то, что это делает.