Есть необходимость организации менеджера памяти для нескольких потоков, решил не изобретать велосипед и сделал, как советуют умные люди через связанный список. Каждый раз, когда запрашивается новый блок памяти, менеджер переберает пустые блоки в поисках первого подходящего. Если в текущем фрагменте памяти нет места то создается новый фрагмент (VirtualAlloc) нужного размера, если размер меньше 64кб то устанавливаем размер фрагмента 64кб если больше то размер выравнивается до ближайшего кратного 64 кб. Все последние блоки каждого фрагмента указывают на первый блок следующего фрагмента. Если в фрагменте нет блоков то фрагмент удаляется (VirtualFree) Сам список в памяти: ; Фрагмент 1 ; ;блок 1 PrevRec dq ; Указатель на адрес предыдущего блока NextRec dq ; Указатель на адрес следующего блока BlockLeng dq ; Размер блока data rb .... ;данные записи ;блок 2 PrevRec dq ; Указатель на адрес предыдущего блока NextRec dq ; Указатель на адрес следующего блока BlockLeng dq ; Размер блока data rb .... ;данные записи ..... ; Фрагмент 2 ; ;блок 1 PrevRec dq ; Указатель на адрес предыдущего блока NextRec dq ; Указатель на адрес следующего блока BlockLeng dq ; Размер блока data rb .... ;данные записи ;блок 2 PrevRec dq ; Указатель на адрес предыдущего блока NextRec dq ; Указатель на адрес следующего] блока BlockLeng dq ; Размер блока data rb .... ;данные записи ..... для того чтобы избежать появление множества мелких фрагментов в начале списка поиск свободного места начинается там где заканчивается предыдущий поиск. И при проектировании менеджера столкнулся с рядом вопросов: 1-Вышеописанный менеджер памяти на практики будет эффективней простого вызова HeapAlloc с выделением нужного размера памяти для каждого запроса? Ведь системный менеджер кучи создавался мелгомягкими именно с целью эффективного управления памятью при многочисленных вызовах? 2-Как избежать фрагментации, много памяти уходит между блоками в списка, нередки случае когда гдето в самом конце весит используемый блок на 1 кб и из-за него нельзя освободит HeapFree на 1 мб. С данными в блоках постоянно работают потоки. 3-При больших размерах списка его перебор занимает большое время есть методика ускоряющая поиск нужного по размерам свободного блока? 4-Может быть имеет смысл вместо создания нового фрагмента через VirtualAlloc простот создать растущею кучу и делать HeapRealloc каждый раз когда нужно изменить ее размеры? 5-Оптимальный вариант для детектирования отсутсвия блоков в фрагменте? П.С. список двунаправленный ошибся в названии темы.
у меня есть самописный менеджер памяти... используется куча, чтобы не думать о фрагментации и быстродействии... для синхронизации между потоками используется ивент под виндой и птредовый мьютекс под линуксами... и кстати HeapRealloc изменяет размер блока выделенного на куче, а не саму кучу...
если на асме можешь залить куда нибуть? Несовсем понял как фрагментацию уменьшить? сама куча ведь будет фрагментированна?
- чтобы избежать лишних вызовов системных процедур HeapAlloc/Free и тд.( я думаю вы имеете ввиду что каждый поток должен сам вызывать HeapAlloc/Free с запросом нужного размера) - постараться уменьшит фрагментацию. - чтобы знать.
Да такое впечатление что системный вообще не оптимизирован никак. Так что свой будет быстрее. Можно, но усложняя менеджер. Обычно для маленьких блоков. Для каждого размеа создают свой список. А эти списки хранятся в единой таблице. Хранить размер выделенного блока. Вопрос не поняет. Ты же по 64 килобайта выделяешь откуда 1мб взялся? Для избавления фрагментации нужно 2 метода. Слияния соседних свободных блоков и выделять данные по минимуму.
Ой ли? Быстрее - для каких паттернов использования? Системный виндовый хип весьма неплохо оптимизирован, начиная с Висты. Написать что-то более быстрое можно, но, в основном, для конкретных стратегий выделения памяти (т.е., это не будет хип общего назначения). Универсальный хип сделать намного быстрее виндового - задача не очень тривиальная.
Вот так прямо в лоб и используется ивент? Что в этом случае с производительностью на множестве потоков? Да и по поводу фрагментации... оно действительно лучше виндового LFH? А насколько лучше? А как это измеряли?
Взаимоисключающие параграфы. Нет, и даже близко по эффективности не дотянет до простого HeapAlloc. Советую посмотреть, как устроены промышленные менеджеры хипа. Тот же Hoard, например.
у майкрософта есть Low Fragmentation Heap. кажется, они попёрли её у Борланда. чтобы создать её надо вызвать HeapSetInformation с параметром HeapInformation = 2. подробности смотри http://msdn.microsoft.com/en-us/library/aa366705(v=vs.85).aspx