Менеджер памяти в одноправленном связанном списке.

Тема в разделе "WASM.BEGINNERS", создана пользователем Sercher, 19 апр 2011.

  1. Sercher

    Sercher New Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    59
    Есть необходимость организации менеджера памяти для нескольких потоков, решил не изобретать велосипед и сделал, как советуют умные люди через связанный список. Каждый раз, когда запрашивается новый блок памяти, менеджер переберает пустые блоки в поисках первого подходящего. Если в текущем фрагменте памяти нет места то создается новый фрагмент (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-Оптимальный вариант для детектирования отсутсвия блоков в фрагменте?
    П.С. список двунаправленный ошибся в названии темы.
     
  2. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.315
    у меня есть самописный менеджер памяти... используется куча, чтобы не думать о фрагментации и быстродействии... для синхронизации между потоками используется ивент под виндой и птредовый мьютекс под линуксами... и кстати HeapRealloc изменяет размер блока выделенного на куче, а не саму кучу...
     
  3. Sercher

    Sercher New Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    59
    если на асме можешь залить куда нибуть?
    Несовсем понял как фрагментацию уменьшить? сама куча ведь будет фрагментированна?
     
  4. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.315
    нет, не на асме...

    в куче уже все придумано за вас, зачем вам изобретать велосипед?
     
  5. Sercher

    Sercher New Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    59
    - чтобы избежать лишних вызовов системных процедур HeapAlloc/Free и тд.( я думаю вы имеете ввиду что каждый поток должен сам вызывать HeapAlloc/Free с запросом нужного размера)
    - постараться уменьшит фрагментацию.
    - чтобы знать.
     
  6. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    [решил, что пост получился не в тему]
     
  7. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    Да такое впечатление что системный вообще не оптимизирован никак. Так что свой будет быстрее.

    Можно, но усложняя менеджер. Обычно для маленьких блоков. Для каждого размеа создают свой список. А эти списки хранятся в единой таблице.
    Хранить размер выделенного блока.

    Вопрос не поняет. Ты же по 64 килобайта выделяешь откуда 1мб взялся?
    Для избавления фрагментации нужно 2 метода. Слияния соседних свободных блоков и выделять данные по минимуму.
     
  8. Ursus

    Ursus Member

    Публикаций:
    0
    Регистрация:
    15 мар 2006
    Сообщения:
    238
    Адрес:
    Russia
    Ой ли? Быстрее - для каких паттернов использования?
    Системный виндовый хип весьма неплохо оптимизирован, начиная с Висты. Написать что-то более быстрое можно, но, в основном, для конкретных стратегий выделения памяти (т.е., это не будет хип общего назначения). Универсальный хип сделать намного быстрее виндового - задача не очень тривиальная.
     
  9. Ursus

    Ursus Member

    Публикаций:
    0
    Регистрация:
    15 мар 2006
    Сообщения:
    238
    Адрес:
    Russia
    Вот так прямо в лоб и используется ивент? Что в этом случае с производительностью на множестве потоков?
    Да и по поводу фрагментации... оно действительно лучше виндового LFH? А насколько лучше? А как это измеряли?
     
  10. Ursus

    Ursus Member

    Публикаций:
    0
    Регистрация:
    15 мар 2006
    Сообщения:
    238
    Адрес:
    Russia
    Взаимоисключающие параграфы.


    Нет, и даже близко по эффективности не дотянет до простого HeapAlloc.
    Советую посмотреть, как устроены промышленные менеджеры хипа. Тот же Hoard, например.
     
  11. sergegers

    sergegers New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2008
    Сообщения:
    172
    у майкрософта есть Low Fragmentation Heap. кажется, они попёрли её у Борланда. чтобы создать её надо вызвать HeapSetInformation с параметром HeapInformation = 2. подробности смотри http://msdn.microsoft.com/en-us/library/aa366705(v=vs.85).aspx