Общий пул памяти — как? - Проблема дизайна

Я создаю свой собственный пул памяти для небольших и очень часто используемых объектов. Я хорошо разбираюсь в распределении и самом d-распределении.

Вот макет моего пула

class CPool
{ 
    unsigned int        m_uiBlocks;     
    unsigned int        m_uiSizeOfBlock;    
    unsigned int        m_uiFreeBlocks; 
    unsigned int        m_uiInitialized;    
    unsigned char      *m_pMemStart;        
    unsigned char      *m_pNext;            

    public:
            CPool();
            ~CPool();

            void                CreatePool(size_t sizeOfEachBlock,  unsigned int numOfBlocks);
            void                DestroyPool();

            unsigned char*      AddrFromIndex(unsigned int i) const;
            unsigned int        IndexFromAddr(const unsigned char* p) const;

            void*               Allocate();
            void                DeAllocate(void* p);
};

Я бы хотел, чтобы у каждого класса был свой пул. Теперь, если какой-то класс должен использовать этот пул, необходимо, чтобы

  1. Они вызывают CreatePool() с размером и количеством_объектов.
  2. Они либо вызывают параметризованные new и delete, либо перегружают операторы и вызывают из них функции Allocate и DeAllocate.
  3. вызовите 'DestroyPool()'

Меня больше беспокоят звонки типа Derived *derObj = new (poolObj)Derived();. Здесь пользователь может забыть poolObj, и этого объекта вообще не будет в моей куче. Конечно, для этого у меня есть глобальная функция, например

inline void* operator new(size_t size, CPool&  objPool)
{
    return objPool.Allocate();
}

Поэтому хотелось бы задать конкретные вопросы:

  1. Как мне перепроектировать класс моего пула, чтобы, если клиент вызывает Derived *derObj = new Derived();, у меня была возможность выделить память из моего пула. Это вообще возможно?

  2. Есть ли способ распознать type объекта? Чтобы CreatePool и DestroyPool тоже можно было убрать из клиентского кода? Но мне нужно быть очень осторожным, чтобы для каждого «типа» был только один пул.

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


person Adorn    schedule 09.12.2014    source источник
comment
Вы можете перегрузить новый, en.cppreference.com/w/cpp/memory/new /operator_new, но, честно говоря, это выходит за рамки того, что вам нужно. В конце концов, мы не можем принять хорошие дизайнерские решения о том, для чего вы будете использовать это... как говорится, вы можете выделить и освободить только один тип (и ни один из его производных), что заставляет меня задаться вопросом, почему конец user не стал бы просто использовать std::vector‹T› и давать T состояние зомби.   -  person IdeaHat    schedule 09.12.2014
comment
Я экспериментирую, чтобы увидеть, получу ли я прирост производительности. Это для моего движка частиц OpenGL. Я знаю реализацию MS C++ 11, которая увеличивает память в два раза, так что да, я согласен, что векторов должно быть достаточно, но все же интересно, как может выглядеть дизайн?   -  person Adorn    schedule 09.12.2014
comment
Вы правы в деньгах, ничего не получая от этого пользовательского пула. Векторы сильно меня побили..:D:D. Хотя мне лучше с новым и удалить. Я просто почувствовал, что означает оптимизированный код. Я выделяю один большой кусок памяти только один раз и выделяю из него. С другой стороны, векторы (специфичные для MS) перераспределяются в порядке 2 ^ alloc_index, который растет как 1, 2, 4, 8 16, 32 и т. д., но все же они очень сильно бьют мой код. Я хочу узнать больше об этом программировании ..   -  person Adorn    schedule 10.12.2014