使用数组来获得最佳的内存对齐和缓存使用,有必要吗?

发布于 2024-09-02 17:59:39 字数 468 浏览 0 评论 0原文

这些天我非常关注性能,因为我正在开发我的第一个游戏引擎。我不是 C++ 专家,但经过一些研究,我发现了缓存和内存对齐的重要性。

基本上我发现,如果您需要一起访问它们(例如在循环中),建议特别对齐内存。

现在,在我的项目中,我正在制作游戏对象管理器,并且我正在考虑拥有一系列游戏对象引用。这意味着我将拥有一个又一个对象的实际记忆。

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

但是,由于我将实现基于组件的设计,其中游戏对象将具有组件列表(网格、刚体、变换等),因此我会通过数组获得一些东西吗?

不管怎样,我看到有些人只是使用简单的 std::map 来存储游戏对象。那么你们觉得怎么样?

使用组件模型是否会更好?

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 references. 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半城柳色半声笛 2024-09-09 17:59:39

互联网上有大量关于缓存利用的资源,但您可能想研究每个程序员都知道什么应该了解内存以更好地理解缓存和内存系统。

不过,简单点 - 让您的对象很好地适合缓存行并分离“热”和“冷”数据。

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.

ゞ花落谁相伴 2024-09-09 17:59:39

如果您不熟悉内存访问和缓存使用,我会推荐 Nikolai 的链接“每个程序员都应该了解内存”。

至于手头的问题:

我建议将每个组件类型存储在它们自己的池中,并将它们存储在连续的数组中。例如:

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

当您分配GameObject(也称为将其从池中拉出)时,分配该对象所需的特定组件。

现在,您应该避免对组件执行此操作:

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

相反,您可以这样处理:

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

如果您确实需要原始的 GameObject(或该对象的其他组件),您可以在每个组件中存储一些数据(例如游戏对象的索引)。通过该对象的索引,您可以访问其他 ComponentPool 中的其他组件。

这一切有什么意义呢?将功能分成特定的块或“作业”变得非常容易。然后,如果您拥有彼此不依赖的组件,则可以并行处理它们(对于“未来”性能很重要)。

有关这方面的更多信息,我建议您查看有关 Insomniac Games 开发的动态组件系统的演示(请务必阅读演讲者注释):https://docs.google.com/present/edit?id=0ATIohmzo6z7TZGhjbmhidnFfMTg1MWNkcTJmcWZ4&hl=en

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文