New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Are multithreaded component system updates possible? #61

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

Comments

Projects
None yet
2 participants
@LearnCocos2D

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

This comment has been minimized.

Show comment
Hide comment
@miguelmartin75

miguelmartin75 Oct 22, 2015

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
Owner

miguelmartin75 commented Oct 22, 2015

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 join this conversation on GitHub. Already have an account? Sign in to comment