|
Аллокатор для Cortex-M3, лучшая стратегия выделения памаяти? |
|
|
|
May 28 2012, 15:16
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046

|
Как ни крути, а динамическая память всеравно рано или поздно становится необходимой... Готовые реализации использовать не могу по многим причинам(необходимость иметь несколько арен, thread-safety итп). Нужен аллокатор, который будет давать минимальную фрагментацию в реальных условиях,минимальный обьем служебной памяти, производительность не особо важна, тк размер арены от силы 32кб.
Реальные условия - одни блоки памяти живут практически forever, другие выделяются/освобождаются подобно стековым переменным - в начале/конце функции соответственно. Блоки разной длины, от 16 до 1024 байт, редко больше. Юзать стек для этого не канает, тк нужно резервировать большие стеки для каждого потока, а это память будет использована на 5-10% в 90% времени. В основном такое поведение имеет место в GUI и всяких обменах сообщениями, где сами алгоритмы гораздо тяжелее, чем аллокатор.
Пока сделал классическую реализацию best-fit, из служебных полей только размер,бит free/used в начале и в конце блока для облегчения free() и слияния соседних пустых блоков, тобышь заголовок весит 8 байт. Работает все гуд, но хз как оно будет при длительной работе девайса(ну там месяц,2,3). Курил всякие разные реализации, но там делается упор в основном на производительность, а про фрагментацию редко где упоминается. По рандом-бенчмаркам best-fit типа рулит, но смущает его тенденция к накоплению кучи маленьких(малоюзабельных) блоков. First-fit, даже на простых тестах в моих реальных условиях показал гораздо худшую фрагментацию, чем best-fit. next-fit еще хуже.
Если кто-то имел дело с использованием,разработкой аллокаторов - буду благодарен за любую информацию...
|
|
|
|
|
 |
Ответов
|
May 29 2012, 13:15
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046

|
Цитата Раз у вас не хватает памяти чтобы распределить её в виде static или на стеке для всех потоков, значит возможна ситуация (и даже с большей вероятностью), когда много потоков запросит больше памяти чем есть. Таки ваша правда... Но работать с динамикой гораздо удобнее, чем передавать в каждую функцию указатели на буфферы, да еще и следить везде за размером. Потом это не просто буфферы, а там классы, программа будет пестреть reinterpret_cast, что вообще не красиво и склонно к образованию разных багов. В принципе серьезно задумываюсь над стеком, разделить тяжелые потоки и легкие отдельно. надо написать хороший анализатор стека, чтобы indirect-высовы понимал(виртуальные классы), рекурсия - фиг с ней, редко где применяется. Сейчас я сделал анализатор стека, но он понимает все, кроме индирект call...  кому надо - могу дать. Цитата При таком использовании может подойти аллокатор, который выделяет память последовательно из пула фиксированного размера и не освобождает её. Освобождается весь пул при выходе из функции. А пулы памяти можно выделять, например, с помощью bitmap allocator. Да, вариант тоже неплох, обдумаем, спасибо
|
|
|
|
|
May 29 2012, 15:19
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(brag @ May 29 2012, 19:15)  Таки ваша правда... Но работать с динамикой гораздо удобнее, чем передавать в каждую функцию указатели на буфферы, да еще и следить везде за размером. Потом это не просто буфферы, а там классы, программа будет пестреть reinterpret_cast, что вообще не красиво и склонно к образованию разных багов. А зачем? Или вы про вызов конструкторов классов для буфера? Но что мешает явно его вызвать: char buf[N]; new (buf) ClassName(...); ClassName *p = (ClassName *)buf; ...
|
|
|
|
|
May 29 2012, 18:13
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(jcxz @ May 29 2012, 18:19)  char buf[N]; new (buf) ClassName(...); ClassName *p = (ClassName *)buf; Ну так этот «С-шный каст» ничем не лучше reinterpret_cast<> Впрочем, тут без кастов можно и нужно. Раз уж placement new используется, его надо и использовать правильно: Код char buf[ sizeof(ClassName) ];
ClassName *p = new (buf) ClassName(...); p.s. ещё тут
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
Сообщений в этой теме
brag Аллокатор для Cortex-M3 May 28 2012, 15:16 Forger Цитата(brag @ May 28 2012, 19:16) Если кт... May 28 2012, 15:37 AlexandrY Цитата(Forger @ May 28 2012, 18:37) По се... May 29 2012, 06:31  Forger Цитата(AlexandrY @ May 29 2012, 10:31) Ка... May 29 2012, 08:08 SasaVitebsk Цитата(Forger @ May 28 2012, 18:37) А обы... May 29 2012, 13:42 brag Спасибо.
Дефрагментатор не годится, тк мы не може... May 28 2012, 16:28 Forger Цитата(brag @ May 28 2012, 20:28) А про н... May 28 2012, 17:01 brag по кучам перечитал всякого много, в тч. Кнута и вс... May 28 2012, 17:08 scifi Цитата(brag @ May 28 2012, 19:16) Реальны... May 28 2012, 18:24 brag Чистый стек не идет. Потоков много, вызывающих одн... May 28 2012, 18:46 jcxz Цитата(brag @ May 29 2012, 00:46) Чистый ... May 29 2012, 02:24 neiver Цитата(brag @ May 28 2012, 22:46) Чистый ... May 29 2012, 11:50 brag Касты с char не прокатят, char buf[ sizeof(ClassNa... Jun 7 2012, 12:49
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|