Я использую в основном O(1) Small Block Memory Manager (SBMM). В основном это работает следующим образом:
1) Он выделяет большие суперблоки из ОС и отслеживает начальный и конечный адреса как диапазон. Размер SuperBlock регулируется, но 1 МБ — это довольно хороший размер.
2) SuperBlocks разбиты на блоки (также регулируемые по размеру... 4K-64K хорошо, в зависимости от вашего приложения). Каждый из этих блоков обрабатывает распределения определенного размера и хранит все элементы в блоке в виде односвязного списка. Когда вы выделяете суперблок, вы создаете связанный список свободных блоков.
3) Выделение предмета означает А) проверку наличия блока с бесплатными предметами такого размера, а если нет, выделение нового блока из суперблоков. Б) Удаление элемента из списка свободных блоков.
4) Освобождение элемента по адресу означает A) поиск суперблока, содержащего адрес(*) B) поиск блока в суперблоке (вычтите начальный адрес суперблока и разделите на размер блока) C) перемещение элемента обратно в список бесплатных элементов блока.
Как я уже говорил, этот SBMM очень быстрый, поскольку работает с производительностью O(1)(*). В версии, которую я реализовал, я использую AtomicSList (похожий на SLIST в Windows), так что это не только производительность O(1), но и ThreadSafe и LockFree в реализации. На самом деле вы можете реализовать алгоритм, используя Win32 SLIST, если хотите.
Интересно, что алгоритм выделения блоков из суперблоков или элементов из блоков приводит к почти идентичному коду (оба являются O(1) выделениями из свободного списка).
(*) Суперблоки расположены в карте диапазона со средней производительностью O(1) (но потенциальным O(Lg N) для наихудшего случая, где N — количество суперблоков). Ширина карты диапазона зависит от примерного знания того, сколько памяти вам понадобится, чтобы получить производительность O (1). Если вы превысите лимит, вы потратите немного памяти, но все равно получите производительность O (1). Если вы недооцените, вы приблизитесь к производительности O (Lg N), но N относится к количеству суперблоков, а не к количеству элементов. Поскольку количество SuperBlock очень мало по сравнению с количеством Item (примерно на 20 двоичных порядков в моем коде), оно не так критично, как остальная часть распределителя.
person
Adisak
schedule
28.09.2009