поможет ли аллокатор?
От: maq Россия http://www.maqdev.com
Дата: 11.02.04 11:10
Оценка:
Появилась необходимость сделать контейнер объекта размер которого фиксирован,
но становится известен только в рантайме.
Понятно что в контейнере можно хранить указатели на объекты, но работа
с контейнером максимально критична к производительности, поэтому хочется
чтобы в контейнере хранился сам объект.
Вопрос: можно ли сделать такое при помощи аллокатора? Т.е. сделать некий dummy
класс который помещаем в контейнер, а аллокатор будет для этого класса выделять
реально необходимое количество памяти.
Re: поможет ли аллокатор?
От: Bell Россия  
Дата: 11.02.04 11:21
Оценка:
Здравствуйте, maq, Вы писали:

maq>Появилась необходимость сделать контейнер объекта размер которого фиксирован,

maq>но становится известен только в рантайме.
maq>Понятно что в контейнере можно хранить указатели на объекты, но работа
maq>с контейнером максимально критична к производительности, поэтому хочется
maq>чтобы в контейнере хранился сам объект.
maq>Вопрос: можно ли сделать такое при помощи аллокатора? Т.е. сделать некий dummy
maq>класс который помещаем в контейнер, а аллокатор будет для этого класса выделять
maq>реально необходимое количество памяти.

Как-то ситуация осталась несколько неясной (для меня по крайней мере).
Что за контейнер?
Что именно подразумевается под "работа с контейнером максимально критична к производительности"?
Что за класс, объекты которого ты собираешься хранить? (И мне еще интересно, как это объекты одного класса могут иметь разные размеры, если это не шаблон класса.)
Любите книгу — источник знаний (с) М.Горький
Re[2]: поможет ли аллокатор?
От: maq Россия http://www.maqdev.com
Дата: 11.02.04 11:38
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, maq, Вы писали:


maq>>Появилась необходимость сделать контейнер объекта размер которого фиксирован,

maq>>но становится известен только в рантайме.
maq>>Понятно что в контейнере можно хранить указатели на объекты, но работа
maq>>с контейнером максимально критична к производительности, поэтому хочется
maq>>чтобы в контейнере хранился сам объект.
maq>>Вопрос: можно ли сделать такое при помощи аллокатора? Т.е. сделать некий dummy
maq>>класс который помещаем в контейнер, а аллокатор будет для этого класса выделять
maq>>реально необходимое количество памяти.

B>Как-то ситуация осталась несколько неясной (для меня по крайней мере).

B>Что за контейнер?

Например vector

B>Что именно подразумевается под "работа с контейнером максимально критична к производительности"?

Это значит что будут постоянные вставки/удаления в контейнер и очень нежелательно при этом все время
вызывать new/delete.

B>Что за класс, объекты которого ты собираешься хранить? (И мне еще интересно, как это объекты одного класса могут иметь разные размеры, если это не шаблон класса.)


Предположим класс у которого есть некие поля и часть переменного размера, но фиксированного для конкретного контейнера.

Собственно не хочется эту переменную часть все время создавать и удалять из кучи.
Если получится все это хранить в векторе, то он просто вырастет до определенного размера, а потом не будет обращений к куче.
Re[3]: поможет ли аллокатор?
От: Bell Россия  
Дата: 11.02.04 11:52
Оценка:
Здравствуйте, maq, Вы писали:

maq>Предположим класс у которого есть некие поля и часть переменного размера, но фиксированного для конкретного контейнера.


maq>Собственно не хочется эту переменную часть все время создавать и удалять из кучи.

maq>Если получится все это хранить в векторе, то он просто вырастет до определенного размера, а потом не будет обращений к куче.

Эээ, я так понимаю, что-то типа этого?

class c
{
   int n_;
   int* ptr_;
public:
   c(int n) n_(n) { ptr_ = new int[n_]; }
   ~c() { delete [ptr_]; }
   //copy ctor, operator =()...
};


Если это так, то можно например обернуть ptr_ умным указателем с подсчетом ссылок.
Или имеется ввиду что-то другое?
Любите книгу — источник знаний (с) М.Горький
Re[4]: поможет ли аллокатор?
От: maq Россия http://www.maqdev.com
Дата: 11.02.04 12:08
Оценка:
B>Эээ, я так понимаю, что-то типа этого?

B>
B>class c
B>{
B>   int n_;
B>   int* ptr_;
B>public:
B>   c(int n) n_(n) { ptr_ = new int[n_]; }
B>   ~c() { delete [ptr_]; }
B>   //copy ctor, operator =()...
B>};
B>


B>Если это так, то можно например обернуть ptr_ умным указателем с подсчетом ссылок.

B>Или имеется ввиду что-то другое?

Собственно да, но умный указатель ничуть не лучше в плане производительности.
Ведь можно сделать так (грубо, не предусмотрено удаление, просто для примера чтобы было понятно):

class c
{
    int n_;
    int size_;
    char offset_;
    
    c(int n, int sz) : n_(n), size_(sz)
    {
        memset(&offset_, 0, size_);
    }
    
public:
    c* allocate(int n, int sz)
    {
        c* ptr = reinterpret_cast<c*>(malloc(size_of(c) + sz - 1));
        new(ptr)c(n, sz);
    }
}


В этом случае мы всего один раз выделяем память для объекта.
А в случае с вектором (если добъемся чтобы аллокатор создавал подобный объект),
размер которого заведомо больше — ни разу.
Re[3]: поможет ли аллокатор?
От: Аноним  
Дата: 11.02.04 12:15
Оценка:
Здравствуйте, maq, Вы писали:

maq>Это значит что будут постоянные вставки/удаления в контейнер и очень нежелательно при этом все время

maq>вызывать new/delete.

Скорее всего хранение объектов (а не указателей) при постоянной вставке/удалении будет медленнее из за постоянного перераспределения памяти под эти объекты.
Re[4]: поможет ли аллокатор?
От: maq Россия http://www.maqdev.com
Дата: 11.02.04 12:47
Оценка:
maq>>Это значит что будут постоянные вставки/удаления в контейнер и очень нежелательно при этом все время
maq>>вызывать new/delete.

А>Скорее всего хранение объектов (а не указателей) при постоянной вставке/удалении будет медленнее из за постоянного перераспределения памяти под эти объекты.


Нет, так как в моем случае вставка указателя будет всегда сопровождаться аллокацией всего объекта
Re[5]: поможет ли аллокатор?
От: Аноним  
Дата: 11.02.04 13:14
Оценка:
Здравствуйте, maq, Вы писали:

maq>Нет, так как в моем случае вставка указателя будет всегда сопровождаться аллокацией всего объекта


что быстрее, вызвать new T + realloc(size() * sizeof(void*)) + memmov(size() * sizeof(void*)),
или realloc(size() * sizeof(T)) + memmov(size() * sizeof(T)) ???.

При больших размерах T выгоднее хранить указатели.
Re: поможет ли аллокатор?
От: ArtDenis Россия  
Дата: 11.02.04 13:15
Оценка:
Здравствуйте, maq, Вы писали:

maq>Появилась необходимость сделать контейнер объекта размер которого фиксирован,

maq>но становится известен только в рантайме.
Ээээ... что-то я не понял, нужно будет хранить объекты разных типов или одного типа?
... << RSDN@Home 1.1.2 stable >>
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[6]: поможет ли аллокатор?
От: maq Россия http://www.maqdev.com
Дата: 11.02.04 13:21
Оценка:
maq>>Нет, так как в моем случае вставка указателя будет всегда сопровождаться аллокацией всего объекта

А>что быстрее, вызвать new T + realloc(size() * sizeof(void*)) + memmov(size() * sizeof(void*)),

А>или realloc(size() * sizeof(T)) + memmov(size() * sizeof(T)) ???.

А>При больших размерах T выгоднее хранить указатели.


Понятно, забыл уточнить размер T порядка 100-200 байт.
Так что выгоднее хранить T.
Re[2]: поможет ли аллокатор?
От: maq Россия http://www.maqdev.com
Дата: 11.02.04 13:21
Оценка:
maq>>Появилась необходимость сделать контейнер объекта размер которого фиксирован,
maq>>но становится известен только в рантайме.
AD>Ээээ... что-то я не понял, нужно будет хранить объекты разных типов или одного типа?

Одного типа, но размер которого известен только в рантайме
Re[5]: поможет ли аллокатор?
От: Bell Россия  
Дата: 11.02.04 13:24
Оценка:
Здравствуйте, maq, Вы писали:

Не нравится мне что-то такая идея. А как быть с конструктором копирования и оператором присваивания?
Быть может стоит стоит определить в классе буфер подходящего размера — чтобы для всех возможных значений size подходил... (это если конечно значения этого самого size не сильно различаются, и можно допустить перерасход памяти).
Или сделать этот класс шаблонным...
Любите книгу — источник знаний (с) М.Горький
Re[3]: поможет ли аллокатор?
От: Bell Россия  
Дата: 11.02.04 13:26
Оценка:
Здравствуйте, maq, Вы писали:

maq>>>Появилась необходимость сделать контейнер объекта размер которого фиксирован,

maq>>>но становится известен только в рантайме.
AD>>Ээээ... что-то я не понял, нужно будет хранить объекты разных типов или одного типа?

maq>Одного типа, но размер которого известен только в рантайме

Как я уже сказал выше — это повлечет трудности при копировании таких объектов.
Любите книгу — источник знаний (с) М.Горький
Re[6]: поможет ли аллокатор?
От: maq Россия http://www.maqdev.com
Дата: 11.02.04 13:27
Оценка:
B>Не нравится мне что-то такая идея. А как быть с конструктором копирования и оператором присваивания?
С конструктором все нормально — переменная часть это POD структура, простое копирование

B>Быть может стоит стоит определить в классе буфер подходящего размера — чтобы для всех возможных значений size подходил... (это если конечно значения этого самого size не сильно различаются, и можно допустить перерасход памяти).

B>Или сделать этот класс шаблонным...
Не получится. Размер передается как параметр COM объекту. Перерасход памяти допускать нельзя — будет создаватся
очень много таких объектов (миллионы)
Re[7]: поможет ли аллокатор?
От: Bell Россия  
Дата: 11.02.04 13:50
Оценка:
Здравствуйте, maq, Вы писали:

B>>Не нравится мне что-то такая идея. А как быть с конструктором копирования и оператором присваивания?

maq>С конструктором все нормально — переменная часть это POD структура, простое копирование

Ой ли?

c* pc1 = c::allocate(1, 20);
c* pc2 = c::allocate(1, 40);

*pc1 = *pc2;


И че?
Любите книгу — источник знаний (с) М.Горький
Re[8]: поможет ли аллокатор?
От: maq Россия http://www.maqdev.com
Дата: 11.02.04 13:55
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, maq, Вы писали:


B>>>Не нравится мне что-то такая идея. А как быть с конструктором копирования и оператором присваивания?

maq>>С конструктором все нормально — переменная часть это POD структура, простое копирование

B>Ой ли?


B>
B>c* pc1 = c::allocate(1, 20);
B>c* pc2 = c::allocate(1, 40);

B>*pc1 = *pc2;
B>


B>И че?



Этого не требуется. Я же сказал, размер фиксирован, но становится известен только в рантайме.
Re: поможет ли аллокатор?
От: maq Россия http://www.maqdev.com
Дата: 11.02.04 14:26
Оценка:
Проанализировал собственно я это дело, и пришел к печальному выводу:
аллокатор тут не поможет

все дело в итераторах, они основываются на размере объекта для перемещения,
имеется в виду vector

А жаль...
Re[2]: поможет ли аллокатор?
От: Bell Россия  
Дата: 11.02.04 14:36
Оценка: 4 (1)
Здравствуйте, maq, Вы писали:

maq>Проанализировал собственно я это дело, и пришел к печальному выводу:

maq>аллокатор тут не поможет

maq>все дело в итераторах, они основываются на размере объекта для перемещения,

maq>имеется в виду vector

maq>А жаль...


Быть может стоит попробовать такой вариант:

class my_allock
{
   friend class holder;
   char* ptr_;
   my_allock();
   my_allock(const my_allock&);
   my_allock& operator = (const my_allock&);
   static char* allocate();
   static void deallocate(char* ptr);
}; 

class holder
{
   int n_;
   static int size_;
   char* ptr_;
public:
   static void set_size(int size) { size_ = size; }
   holder(int n) : n_(n) { ptr_ = my_allock::allocate(); }
   
   holder(const holder& rhs) : n_(rhs.n_)
   {
      ptr_ = my_allock::allocate();
   }

   holder& operator = (const holder& rhs)
   {
      if(this != &rhs)
      {
         n_ = rhs.n_;
         memcpy(ptr_, rhs.ptr_, size_);
      }
   }

   ~holder() { my_allock::deallocate(ptr_); }
};


Т.е. my_allock выделяет память большими кусками, а потом раздает указатели на различные места большого куска в ответ на allocate. Ну и помечает блок как "свободный" в ответ на deallocate. Поскольку размер у тебя фиксированный, то реализуется все это дело достаточно просто.
Неплохой пример есть у Александреску, в главе про small object allocator.
Любите книгу — источник знаний (с) М.Горький
Re[3]: поможет ли аллокатор?
От: maq Россия http://www.maqdev.com
Дата: 11.02.04 14:52
Оценка:
maq>>Проанализировал собственно я это дело, и пришел к печальному выводу:
maq>>аллокатор тут не поможет
maq>>все дело в итераторах, они основываются на размере объекта для перемещения,
maq>>имеется в виду vector

maq>>А жаль...


B>Быть может стоит попробовать такой вариант:

... skipped...

Это понятно — можно написать отптимизированный аллокатор для моего случая,
но к сожалению этот аллокатор не будет STL совместимый.
Re[4]: поможет ли аллокатор?
От: Bell Россия  
Дата: 11.02.04 15:04
Оценка:
Здравствуйте, maq, Вы писали:

maq>Это понятно — можно написать отптимизированный аллокатор для моего случая,

maq>но к сожалению этот аллокатор не будет STL совместимый.

Aлокатор my_alloc никакого отношения к STL (к аллокатору контейнера) не имеет, а посему не может быть "STL несовместимым". Для того, чтобы объект мог использоваться в качестве элемента стандартного контейнера необходимо, чтобы он был assignable и copy-constractible. Объекты класса holder этим требованиям удовлетворяют.
Так что я проблемы не вижу.
Любите книгу — источник знаний (с) М.Горький
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.