C ++中的复杂内存管理问题

时间:2012-07-11 18:53:46

标签: c++ performance memory-management containers

我需要在C ++中设想一个有效的粒子系统,它可以处理大量粒子并施加力。

以下是要求:

  • 动态地有效地创造和消耗大量粒子和力量。

  • 粒子存储x / y / z位置和速度,质量,空气摩擦以及其他一些其他属性。

  • 不需要扩展粒子(没有继承图)。

  • Forces是多态对象,主要有一个getAcceleration()虚方法。

  • 可以对一个粒子施加几种或没有力。

  • 一种力只适用于一个粒子,当这个粒子死亡时,力量没有更多意义,应该删除。

  • 力可能涉及多个粒子(包括它所应用的粒子)。

  • 当一个粒子死亡(被移除)时,根据力的类型,涉及它的力可能也可能不会死亡。

  • 引擎必须能够遍历每一帧的所有粒子和所有力才能执行计算

我希望有一个漂亮而清晰的对象模型,以便能够很好地维护和扩展。

其他信息:

可以显示力(在屏幕上绘制小箭头),因此将它们建模为真实物体可能会很不错。
粒子通常由“物理对象”创建,它创建一个或多个粒子(对它们施加力)并且可以随时移除它们(如果物理对象变得不动,如果它离开屏幕,或者任何原因) 。
(请注意,力不仅会由“物理对象”创建。)

到目前为止,我已经开始尝试最小化动态分配,因为它们很慢,并且粒子很可能每秒都会出现并且大量死亡。

#include <vector>

typedef double nb_t;

struct Particle {
    nb_t x, y;
    nb_t sx, sy;
    nb_t mass;
    nb_t air_friction;
};

class Force {
public:
    virtual nb_t get_x_component() = 0;
    virtual nb_t get_y_component() = 0;
    virtual ~Force() = 0;
};

class Engine {
protected:
    std::vector<Particle> particles;
    std::vector<Force*> forces;
public:
    void refresh();
    void addParticle(Particle& p);
    void removeParticle(int index);
    // ...
};

但是,粒子的所有者(或者更确切地说是它的创造者,物理对象)应该如何跟踪它的粒子,并能够命令它们被移除?
我认为智能指针可能很有用,但我不确定引用计数是否合适,因为死亡的粒子应立即从​​内存中移除以让其他人分配。

此外,是不是有一个STL容器可以将我的对象存储在一个数组中(比如矢量),而不考虑顺序(unordered_vector?)但是会放置最后一个元素而不是我们尝试删除的元素,以便元素删除不需要翻译所有以下元素?

您认为最好的是什么?尝试保持效率,清晰度和可扩展性会有什么好处?

2 个答案:

答案 0 :(得分:1)

关于创建和删除您想要永远不想调用新对象或删除对象的对象,或尝试将其最小化。可以通过创建内存池并将其用于对象分配来实现此最小化。

看起来你想要一个对象池,一个用于粒子,一个用于力。

http://pastie.org/private/ivmu9ogvrf5vurjrwuqmka

该代码是一个非常简单且不太强大的内存池,但可以为您提供更好的实现方法。

答案 1 :(得分:0)

以下是有关架构的小型观察,我将让其他人解决内存管理本身的问题

虚拟调用需要一次处理尽可能多的粒子,因此您可能希望通过getAcceleration()computeAccelerationsForParticles( std::vector<int>& particleIndices)等更密集的内容重新考虑单个computeAccelerationsForParticles( ParticleGroup& particleGroup)界面。通过这种方式,虚拟呼叫的开销从每个粒子一次扩展到每个力组一次

这种架构意味着您需要按强制组跟踪粒子。如果你想显示粒子特定数据(比如力)你可能会添加一个只在非空时更新的粒子调试结构,所以你在做无窗口时不会有这样的开销。模拟