开发者

using arrays to get best memory alignment and cache use, is it necessary?

I'm all about performance these days cause I'm developing my first game engine. I'm no c++ expert but after some research I discovered the importance of the cache and the memory alignment.

Basically what I found is that it is recommended to have memory well aligned specially if you need to access them together, for example in a loop.

Now, In my project I'm doing my Game Object Manager, and I was thinking to have an array of GameObjects re开发者_如何学JAVAferences. meaning I would have the actual memory of my objects one after the other.

static const size_t MaxNumberGameObjects = 20;
GameObject mGameObjects[MaxNumberGameObjects];

But, as I will be implementing a component based design in which game objects will have a list of components (Mesh, RigidBody, Transformation, etc), will I be gaining something with the array at all?

Anyway, I have seen some people just using a simple std::map for storing game objects. So what do you guys think?

Am I better off using a pure component model?


There're plenty of resources about cache utilization on the internet, but you probably want to study What Every Programmer Should Know About Memory to get good understanding of cache and memory system.

Quick points though - make your objects fit nicely into cache lines and separate "hot" and "cold" data.


If you're new to memory access and cache usage, I second Nikolai's link to 'What Every Programmer Should Know About Memory.'

As for the question at hand:

I'd recommend storing each component type in their own pools where they'd be stored in contiguous arrays. ex:

ComponentPool<CollisionComponent> mCollisionComponents;
ComponentPool<MeshComponent> mMeshComponents;
...

When you allocate a GameObject (aka pull it from the pool), allocate the specific components that the object needs.

Now, you should avoid doing this with the components:

void SomeCollisionWork() {
    for each object {
        if(object.hasCollisionComponent()) {
            DoCollisionWork(object.collisionComponent)
        }
    }
}

Instead, you can approach it like this:

void SomeCollisionWork() {
    for each allocated component in mCollisionComponents {
        DoCollisionWork(component)
    }
}

If you really needed the original GameObject (or other Components for that object), you could store some data (like, say, the GameObject's index) in each component. With the object's index, you could then access its other Components in the other ComponentPools.

What's the point of all of this? It becomes pretty easy to separate functionality into specific chunks, or 'jobs'. Then, if you have components that aren't dependent upon each other, you can work on them in parallel (important for 'future' performance).

For more on this, I'd recommend looking at this presentation on the dynamic component system that Insomniac Games has developed (be sure to read the speaker notes): https://docs.google.com/present/edit?id=0ATIohmzo6z7TZGhjbmhidnFfMTg1MWNkcTJmcWZ4&hl=en

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜