0
\$\begingroup\$

I'm currently writing a simple ECS architecture for an engine and I have the fundamentals in place but after reading up on this architecture, it is designed in such a way that the memory is contiguous for all of the components and systems.

My understanding is that the components should be stored right after each other so they are not somewhat fragmented in memory? So that way when I update all of the components, the cache prefetcher can help out performance by fetching the next lot of components (limited understanding) without jumping around.

class system1 final
{
public:
        //...


private:
    std::vector<component1>         m_components;
};

class system2 final
{
public:
        //...


private:
    std::vector<component2>         m_components;
};

Then in some manager, you would initialize the systems so that they are as close as possible in memory.

But what if I wanted to allocate additional memory in the systems? Like a few extra buffers for dealing with system-specific information. That would then separate the component buffers so they are no longer next to each other.

class system1 final
{
public:
        //...


private:
    std::vector<component1>         m_components;
    std::vector<int>                m_somebuffer;
    std::vector<int>                m_someOtherBuffer;
};

class system2 final
{
public:
        //...


private:
    std::vector<component2>         m_components;
};
  • Would this cause any problems and does this break the whole ECS principle?
  • What should I be considering here for maximum performance without stumbling on issues later?

I don't want to optimize prematurely but knowing what makes an architecture fast and somewhat optimal during development is an interesting topic for me. Any input is greatly appreciated.

\$\endgroup\$
2
\$\begingroup\$

One goal of the ECS pattern is that each system has all its data closely together so that it doesn't get many cache misses when it iterates over the components it manages. So there is nothing wrong with systems having their own memory buffers for data only required by that system.

However, there is one thing in your architecture which is usually not what you do in an ECS-by-the-book architecture, and that's that each system owns the components it manages. You usually don't have a 1:1 relationship between systems and components. There are often components shared by multiple systems and systems which operate on multiple components. For example, you might have a system MovementSystem which uses the components Position and Velocity and a separate CollisionSystem system which uses the components Position and BoundingBox.

For that reason you usually manage the components by a separate class and then inject the component-arrays into the systems.

\$\endgroup\$
  • \$\begingroup\$ Oh I see. That was my next concern really as I have a few systems that rely on multiple components. Do you have a small example of how this would work? Would there just be a class that holds all components, and the systems would only hold lists of pointers to them? Thanks in advance \$\endgroup\$ – jjmcc Sep 29 at 14:25
  • \$\begingroup\$ @jjmcc Yes, such a class is usually called a "component manager". If you have any follow-up questions, please ask them as separate questions. \$\endgroup\$ – Philipp Sep 29 at 16:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.