如何将内存池概念集成到数据结构中(例如自定义数组)?

时间:2017-01-25 05:25:38

标签: c++ c++11 game-engine pool memory-pool

我一直在使用组件实体系统 很久以前,我想改进它以使用内存池

第1阶段

为简单起见,这是我的古老代码: -

Entity* entity      =new Entity();             
Com_Physic* comPhys =new Com_Physic();  

这是重构的结果: -

Ptr<Entity> entity=centerPool()->createEntity();                   //use pool
Ptr<Com_Physic> comPhys=centerPool()->create<Com_Physic>(entity);  //use pool

它的效果非常好。 (每次使用的时间 - = 10%)

第2阶段

现在我强烈希望在任何地方都能适应记忆池概念 但是,在涉及某些数据结构的情况下,这很难。

这是一个返回某个实体的所有(默认)物理主体的示例函数 它不是一个真正的完整代码,但足以显示有问题的部分: -

class SystemPhysic : public basicSystem {
    //..... other function / field .....
    public: MyArray<PhysicObject*> getAllPhysicBody(Ptr<Entity> entity){
        Ptr<Com_Physic> comPhysic=entity->get<Com_Physic>();
        MyArray<PhysicObject*> allPhy=comPhysic->physicsList; 
                                   //^ #problem
        return allPhy;
    }
};

MyArray<T>是一个类似于std::vector的自定义数组。它使用自己的分配器。

这是它的核心: -

void reserve(int expectedSize){
    //......
    void* databaseNew=operator new [](expectedSize*sizeof(T));
    //......
}

因此,每当我致电MyArray<PhysicObject*>::operator=()时, ...粗略地说,operator new[]将被召唤。 (#problem

记忆再次破碎。

问题

一般数据结构是否应使用内存池概念? 如果是这样,如何将内存池概念专业地集成到数据结构中?

我只是想要一个粗略的想法 完全不包含代码的解决方案是可以接受的。

更多技术信息

MyArray<T>有两种类型的问题: -

  1. MyArray<T>作为组件的字段(例如Com_Physic)。
  2. MyArray<T>作为从系统传递到另一个系统的临时消息。它创建速度快,删除速度快。 (&gt; 70%,生命时间= 1个时间步)
  3. 我有一个想法,将其分为两种情况,ShortLife_MyArray<T>&amp; LongLife_MyArray<T>
    ......但我认为我太复杂,难以维护。

    为了使问题更严重,在真实游戏中,除MyArray<T>之外还有许多种数据结构,例如MyArray<T1,T2>MyMap<T1,T2>MySet<T1,&FunctionPointer>

    我糟糕的解决方案

    这只是显示了我到目前为止的猜测列表。

    解决方案1(单例,静态)

    MyArray<T>MyArray<T1,T2>MyMap<T1,T2>等处创建静态池字段。

    所有类型的数据结构都必须使用该静态池在需要时分配内存。

    GlobalDataStructure::staticPool=topLevel()->poolPtr; 
    //called only once before everything start
    

    缺点: -

    • 这是一个静态变量。 (没有多大意义)
    • 很难找到应该调用全局设置语句的位置。
    • (弱)我只能使用1个游泳池。 (我不确定这是不是一个问题。)
    • (弱)如果我的游戏是多线程的,我必须使用mutex来锁定游泳池。

    解决方案2(占上风)

    MyArray<T>MyArray<T1,T2>MyMap<T1,T2>等中创建非静态池字段。

    每当我想创建一个新的数据结构时,
    ...我必须 传递 共享池(来自顶级游戏逻辑)。

    MyArray<T> arr=MyArray<T>(topLevel()->poolPtr);  //messy
    

    对于不同的情况,可以有许多池。这可能很好。

    当数据结构想要分配时,它必须使用该池。

    缺点: -

    • 我必须为所有类型的数据结构重构所有代码。
    • 我必须 传递 游泳池。代码会更脏一些。
    • (弱)如果我的游戏是多线程的,我必须使用mutex锁定池。

    解决方案3(懒惰的方式)

    不要做任何事情,实体和组件的池应该足够了 其他解决方案是过度工程。

0 个答案:

没有答案