Я ищу реализацию алгоритма распределения кучи на C для микроконтроллера с ограниченным объемом памяти. Я сузил свой поиск до двух вариантов, о которых я знаю, однако я очень открыт для предложений, и я ищу совет или комментарии от любого, у кого есть опыт в этом.
Мои требования:
-Скорость определенно имеет значение, но это второстепенная задача.
- Временной детерминизм не важен - любая часть кода, требующая детерминированной синхронизации в худшем случае, имеет свой собственный метод распределения.
- ГЛАВНОЕ требование – устойчивость к фрагментации. На устройстве работает механизм сценариев lua, для которого потребуется диапазон размеров выделения (тяжелый для 32-байтовых блоков). Главное требование, чтобы это устройство работало в течение длительного времени, не переводя свою кучу в непригодное для использования состояние.
Также примечание:
-Для справки, речь идет о компонентах Cortex-M и PIC32 с памятью от 128K до 16MB или памятью (с упором на нижний предел).
-Я не хочу использовать кучу компилятора, потому что 1) мне нужна стабильная производительность для всех компиляторов и 2) их реализации, как правило, очень просты и одинаковы или хуже для фрагментации.
-двойные непрямые опции недоступны из-за огромной базы кода Lua, которую я не хочу фундаментально изменять и перепроверять.
Мои любимые подходы на данный момент:
1) Иметь бинарный распределитель-друг и жертвовать эффективностью использования памяти (округление до степени двойки). - для этого (как я понимаю) потребуется двоичное дерево для каждого заказа/корзины для хранения свободных узлов, отсортированных по адресу памяти, для быстрого поиска блоков друзей для повторной цепочки.
2) Иметь два бинарных дерева для свободных блоков, одно отсортированное по размеру, а другое отсортированное по адресу памяти. (все ссылки на бинарное дерево хранятся в самом блоке) -распределение было бы лучше всего использовать поиск в таблице по размеру, а затем удалить этот блок из другого дерева по адресу -освобождение будет искать соседние блоки по адресу для повторной цепочки
-Оба алгоритма также потребуют сохранения размера выделения до начала выделенного блока, и блоки будут выходить как степень 2 минус 4 (или 8 в зависимости от выравнивания) . (Если только они не хранят двоичное дерево в другом месте для отслеживания выделений, отсортированных по адресу памяти, что я не считаю хорошим вариантом)
- Оба алгоритма требуют сбалансированного по высоте кода двоичного дерева.
-Алгоритм 2 не требует тратить память на округление до степени двойки.
— В любом случае у меня, вероятно, будет фиксированный банк 32-байтовых блоков, выделенных вложенными битовыми полями для разгрузки блоков такого же размера или меньшего размера, которые будут невосприимчивы к внешней фрагментации.
Мои вопросы:
-Есть ли причина, по которой подход 1 более защищен от фрагментации, чем подход 2?
-Есть ли альтернативы, которые я упустил, которые могли бы соответствовать требованиям?