LINUX.ORG.RU

[C][pool based memory allocator]

 


3

2

Подскажите какую-нибудь приличную сишную библиотеку для работы с памятью через пул объектов. Года 4 назад что-то находил, но название вылетело из головы совершенно.

Лицензия LGPL, BSD, etc...

★★★★★

Последнее исправление: mv (всего исправлений: 1)
Ответ на: комментарий от mv

там есть и интерфейс malloc/realloc/calloc/free, и новый umem_alloc/umem_free/umem_cache_create/umem_cache_alloc/umem_cache_free

главное память выделенную одним, не возвращать через другой.

mukoh
()
Ответ на: комментарий от Boy_from_Jungle

Мне нужен маленький и годный для проприетарщины менеджер пулов. Пул - это регион памяти для выделения одинаковых объектов, предназначен для более реактивного выделения/освобождения память под эти объекты, а также для борьбы с фрагментацией.

mv ★★★★★
() автор топика
Ответ на: комментарий от mukoh

дык это он и есть.. по крайней мере в солярисной инкарнации..

Посмотрел, лицензия плохая.

mv ★★★★★
() автор топика
Ответ на: комментарий от mv

>Мне нужен маленький и годный для проприетарщины менеджер пулов.

Может дурацкий вопрос. Но как насчет того, что бы самому написать? Я не знаю что у тебя там за задача, но есть предположение, что самому написать простенький пул объектов будет быстрее чем тратить время на форумный треп.

pathfinder ★★★★
()
Ответ на: комментарий от pathfinder

Может дурацкий вопрос. Но как насчет того, что бы самому написать? Я не знаю что у тебя там за задача, но есть предположение, что самому написать простенький пул объектов будет быстрее чем тратить время на форумный треп.

Кроме трёпа на форуме есть и другие задачи, которые нужно делать вместо написания пула ;)

mv ★★★★★
() автор топика
Ответ на: комментарий от mv

Вот фантазия на тему. :)

#include <string>

template<typename Obj,int pool_size>
class ObjectPool
{
private:
  Obj obj_arr[pool_size];
  Obj* free_obj_queue[pool_size];
  int tail;
  int head;
  
  Obj* first;
  Obj* last;
public:
  inline ObjectPool()
  {
    tail=0;
    head=0;
    for(int i=0;i<pool_size;i++)
    {
      free_obj_queue[i]=&obj_arr[i];
    }
    
    first=&obj_arr[0];
    last=&obj_arr[pool_size-1];
  }
  
  inline Obj* Alloc()
  {
    if(tail==head) //queue is empty, using standart allocation
    {
      return new Obj;
    }
    else
    {
      Obj* free_object = free_obj_queue[head];
      head++;
      if(head==pool_size)
        head=0;
      
      return free_object;
    }       
  }
  
  inline void Free(Obj* _object)
  {
    if((_object>=first)&&(_object<=last)) //this object from pool
    {
      free_obj_queue[tail]=_object;
      tail++;
      if(tail==pool_size)
        tail=0;
    }
    else
    {
      delete _object;
    }
  }
};

class A
{
public:
  int b;
  int c;
  std::string name;
};

int main()
{
  ObjectPool<A,10>  my_pool;
  
  A* p1 = my_pool.Alloc();
  A* p2 = my_pool.Alloc();
  A* p3 = my_pool.Alloc();
  
  my_pool.Free(p3);
  my_pool.Free(p2);
  my_pool.Free(p1);
  
  return 0;
}

По идее работать должно достаточно быстро. Написано правда наспех, поэтому могут быть ошибки. И есть недостаток - освобожденный объект лучше не освобождать.

pathfinder ★★★★
()
Ответ на: комментарий от pathfinder

Будет ли быстрее операции new аллокатор, который постоянно использует new. Если уже писать, то нужно сделать массив готовых обьектов и искать в них как то эффективно. Например битсетом, конечно самодельным, чтобы сразу int с 0 сравнивать и узнавать есть ли в этом блоке из 32 обьектов нужный поциент.

А чем не подошел Glib?

vertexua ★★★★★
()
Ответ на: комментарий от pathfinder

Нет выравнивания, нет определения пересечения страницы, «горячие» объекты не переиспользуются, и вообще это не Си ;)

mv ★★★★★
() автор топика
Ответ на: комментарий от vertexua

> Если уже писать, то нужно сделать массив готовых обьектов и искать в них как то эффективно. Например битсетом, конечно самодельным, чтобы сразу int с 0 сравнивать

Ты правда думаешь, что это будет быстрее и проще банальнейшего списка квантов? %)

tailgunner ★★★★★
()
Ответ на: комментарий от pathfinder

В С++ есть аллокаторы, я на прошлой неделе делал аллокатор. Он был на основе двух бинарных деревьев, стандартных из STL. В них был заменен аллокатор (чтобы не было аллокатора, юзающего new) на простенький на коленке slab allocator

vertexua ★★★★★
()
Ответ на: комментарий от vertexua

Поправил немного.

#include <string>

template<typename Obj,int pool_size>
class ObjectPool
{
private:
  Obj obj_arr[pool_size];
  Obj* free_obj_queue[pool_size+1];
  int tail;
  int head;
  
  Obj* first;
  Obj* last;
public:
  inline ObjectPool()
  {
    tail=0;
    head=0;
    for(int i=0;i<pool_size;i++)
    {
      free_obj_queue[i]=&obj_arr[i];
    }
    
    head=0;
    tail=pool_size;
    
    first=&obj_arr[0];
    last=&obj_arr[pool_size-1];
  }
  
  inline Obj* Alloc()
  {
    if(tail==head) //queue is empty, using standart allocation
    {
      return new Obj;
    }
    else
    {
      Obj* free_object = free_obj_queue[head];
      head++;
      if(head==(pool_size+1))
        head=0;
      
      return free_object;
    }       
  }
  
  inline void Free(Obj* _object)
  {
    if((_object>=first)&&(_object<=last)) //this object from pool
    {
      free_obj_queue[tail]=_object;
      tail++;
      if(tail==(pool_size+1))
        tail=0;
    }
    else
    {
      delete _object;
    }
  }
};

class A
{
public:
  int b;
  int c;
  std::string name;
};

int main()
{
  ObjectPool<A,10>  my_pool;
  
  A* p1 = my_pool.Alloc();
  A* p2 = my_pool.Alloc();
  A* p3 = my_pool.Alloc();
  
  my_pool.Free(p3);
  my_pool.Free(p2);
  my_pool.Free(p1);
  
  return 0;
}

pathfinder ★★★★
()
Ответ на: комментарий от mv

>Нет выравнивания

Про целесообразность выравнивания подробнее.

нет определения пересечения страницы

ЩИТО?

«горячие» объекты не переиспользуются

Можно доставать не из головы, а из хвоста очереди. Это тебя устроит?

и вообще это не Си ;)

На Си написать тоже самое не проблема

pathfinder ★★★★
()
Ответ на: комментарий от pathfinder

Нет выравнивания

Про целесообразность выравнивания подробнее.

Если объект не выровнен на границу 4-х байт, то скорость на корках падает ажно в 4 раза. На нехалемах хорошо, но они стоят ещё не везде, где надо.

нет определения пересечения страницы

ЩИТО?

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

Можно доставать не из головы, а из хвоста очереди. Это тебя устроит?

Наверное. Но я ещё тайно надеялся найти компактирующий пул, который выделяет новый объект рядом с попрошенным адресом.

На Си написать тоже самое не проблема

Как на твоём примере видно, что, таки, проблема, плюс реально неохота на сях писать больше, чем необходимо. Технических проблем написать нет.

mv ★★★★★
() автор топика
Ответ на: комментарий от mv

> Граница страниц - это тормоз от железнодорожного вагона, плюс неиссякаемый источник глюков в процессорах.

Бгг.

tailgunner ★★★★★
()
Ответ на: комментарий от mv

Но я ещё тайно надеялся найти компактирующий пул, который выделяет новый объект рядом с попрошенным адресом.


ого, это уже серьезно :)

Boy_from_Jungle ★★★★
()
Ответ на: комментарий от vertexua

Кажись я в игноре... А помочь хотел...

glib ради одного только пула слишком жирно тянуть.

mv ★★★★★
() автор топика
Ответ на: комментарий от mv

Так а в чем проблема? Glib не редкость на самом кеданутом десктопе. И в винде работает. А потом еще можно много всяких вкусностей заюзать

vertexua ★★★★★
()
Ответ на: комментарий от vertexua

Так а в чем проблема? Glib не редкость на самом кеданутом десктопе. И в винде работает. А потом еще можно много всяких вкусностей заюзать.

Мне вкусностей не надо. Мне надо очень быстро.

mv ★★★★★
() автор топика
Ответ на: комментарий от mv

> «Бггг»?

Ага. Тебя правда волнуют баги в процесорах, возникающие при пересечении границ страницы?

А, и еще - чем так отличается граница страницы от границы кэш-строки, что граница страницы - аж «тормоз от железнодорожного вагона»?

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Ага. Тебя правда волнуют баги в процесорах, возникающие при пересечении границ страницы?

Конечно! Причём, баг - это не когда система колом встала, а когда на графике латентности появился ничем другим не объяснимый высер.

А, и еще - чем так отличается граница страницы от границы кэш-строки, что граница страницы - аж «тормоз от железнодорожного вагона»?

Другой (ещё один) TLB entry используется.

mv ★★★★★
() автор топика
Ответ на: комментарий от mv

>> Ага. Тебя правда волнуют баги в процесорах, возникающие при пересечении границ страницы?

Конечно! Причём, баг - это не когда система колом встала, а когда на графике латентности появился ничем другим не объяснимый высер.

Ээээ... а что, у вас и программа, и данные помещаются в одну страницу, и никогда границу не пересекает? %) Или ты пишешь суперкритичный по быстродействию кусок?

чем так отличается граница страницы от границы кэш-строки, что граница страницы - аж «тормоз от железнодорожного вагона»?

Другой (ещё один) TLB entry используется.

И снова - как тебе здесь пул поможет? Если тебе надо 2 страницы памяти, то тебе надо не менее двух страниц, и ты всё равно попадешь на другой TLB entry.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Ээээ... а что, у вас и программа, и данные помещаются в одну страницу, и никогда границу не пересекает? %) Или ты пишешь суперкритичный по быстродействию кусок?

2.

И снова - как тебе здесь пул поможет? Если тебе надо 2 страницы памяти, то тебе надо не менее двух страниц, и ты всё равно попадешь на другой TLB entry.

ОДИН объект не должен лежать на границе страниц. Остаток страницы, в который объект не влазит, должен быть выброшен.

mv ★★★★★
() автор топика
Ответ на: комментарий от mv

Что-то мне кажется, что Glib будет быстрее самописного. Если они для этого API специально придумали, то оно на высоте.

vertexua ★★★★★
()
Ответ на: комментарий от vertexua

Что-то мне кажется, что Glib будет быстрее самописного. Если они для этого API специально придумали, то оно на высоте.

Я в большинстве узких мест круче код пишу %) Поэтому на Си посадили :( Временно.

glib реально слишком большой, чтобы ради такой мелкой фигни его использовать.

mv ★★★★★
() автор топика
Ответ на: комментарий от mukoh

Чем именно CDDL тебе плохая? Твою проприетарщину вирусом свободы не заразит..

Знаешь анекдот про двух HR'ов? Свежий HR в первый день на новой работе учится делу у матёрого. Матёрый берёт половину стопки резюме кандидатов и выбрасывает в урну. Молодой: «Как же так? Вы ведь даже не заглянули в них!». Матёрый: «Мы в лузерах не заинтересованы.»

mv ★★★★★
() автор топика
Ответ на: комментарий от mv

>> И снова - как тебе здесь пул поможет? Если тебе надо 2 страницы памяти, то тебе надо не менее двух страниц, и ты всё равно попадешь на другой TLB entry.

ОДИН объект не должен лежать на границе страниц. Остаток страницы, в который объект не влазит, должен быть выброшен

Это понятно. Непонятно другое - при обращении к другому объекту ты всё равно попадешь на другой TLB entry, так в чем профит? В одном месте сэкономил, в другом - потратил сэкономленное.

tailgunner ★★★★★
()
Ответ на: комментарий от mv

> О'кей, убедил. Сам-то с ним работал?

А то.. На соляре правда..

mukoh
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.