Skip to content
This repository was archived by the owner on Mar 12, 2021. It is now read-only.

Are multithreaded component system updates possible? #61

Open
LearnCocos2D opened this issue Oct 21, 2015 · 1 comment
Open

Are multithreaded component system updates possible? #61

LearnCocos2D opened this issue Oct 21, 2015 · 1 comment

Comments

@LearnCocos2D
Copy link

I was wondering in how far anax is multithreading-capable?

  1. Can I write component systems whose update(dt) method iterates over the getEntities list on multiple concurrent threads?
  2. Would it be possible and safe to update multiple component systems concurrently, each on its own thread?

If you don't have a definite answer I'd be okay with "probably not" or other vague statements. Just so I know whether it's worth investigating or not.

I suppose that at least 1. should be doable, and if so, that would be a major differentiator compared to EntityX and Artemis, as their systems call the update method per entity, passing in a reference to the entity.

@miguelmartin75
Copy link
Owner

Can I write component systems whose update(dt) method iterates over the getEntities list on multiple concurrent threads?

Yes this should be possible, unless you are modifying components which is shared between threads. e.g. if two systems are running on two separate threads but they require a Position component from their entities and one or both modify the Position component, then you're bound to run into a data race. You can of course avoid this data race with a mutex, though depending on the situation, it might be more efficient/easier to just run those systems which have overlap in ComponentFilters (require the same components) to be placed/ran in the same thread.

Would it be possible and safe to update multiple component systems concurrently, each on its own thread?

I believe that it is not safe to activate, remove or kill entities from a world in multiple threads. Since I see an obvious data-race with my code (if you look inside the world class), due to me adding the entity to a killed/destroyed/activated/etc. list.

Along with that, even if you don't receive a data-race, there's another issue: if you refresh the world to update every system's entity list, then this refresh/update could occur when another thread is processing it's entities. It would essentially boil down to the following (simplified) situation:

shared variable: System's vector<Entity> entities

Thread 1

// inside your system
for(auto& e : getEntities())
{
    process(e);             
}

Thread 2

system.entities.push_back(e); // which is what happens in world.refresh()                        

So therefore, you would have to sync up a world.refresh() call (i.e. pause all threads until you refresh the world), as otherwise you would run into a data-race. Unless there's a smarter way to avoid the data-race. In fact, I think there is (for the implementation of the library):

  • Keep a temporary buffer of entities that should be added/removed to/from the system.
  • The next time you call getEntities(), this buffer would be cleared and reflect changes on the system's entity list.
  • This temporary buffer will have to be locked, in order to avoid more data-races

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants