Opened 8 years ago

Closed 7 years ago

Last modified 7 years ago

#4046 closed enhancement (invalid)

[Patch] Improve performance of ComponentManager when sending messages

Reported by: wraitii Owned by:
Priority: Should Have Milestone:
Component: UI & Simulation Keywords: patch
Cc: Patch:

Description

Sending messages is rather slow. A rather simple profiling of an MP game has shown that there is an overhead anywhere between 5 and 20% simply for iterating or finding the right components when passing messages. The code uses std::map, which is rather inefficient. It would probably be a good idea to replace some or all std::map<entity_id_t, XX> with the EntityMap container which was made for this purpose and performance.

We also probably should use the entity component Cache in PostMessage

Furthermore, many components are subscribed globally to some messages, which is a real slowdown. The biggest culprit is onGlobalOwnershipChanged in the JS components Guard, Formation and GarrisonHolder. We should rather implement a "SubscribetoEntity" function to only poll messages for the entities we want. SendGlobalMessages seems to occupy around 10% of the runtime, so this is not really a small thing.

Finally, functions such as LookupEntityHandle or QueryInterface could be made more efficient.

Attachments (6)

EntityMapForComponents.patch (14.0 KB ) - added by wraitii 8 years ago.
Fix bit operation
EntityMapForComponents.2.patch (24.9 KB ) - added by wraitii 8 years ago.
Version using an extension of EntityMap?
EntityMapForComponents.3.patch (27.2 KB ) - added by wraitii 8 years ago.
Tame the monster
EntityMapForComponents.4.patch (44.3 KB ) - added by wraitii 8 years ago.
RC
messageChangesV0.patch (52.0 KB ) - added by wraitii 8 years ago.
AiProxyOptim.patch (4.2 KB ) - added by wraitii 7 years ago.
git patch for the above branch

Download all attachments as: .zip

Change History (15)

comment:1 by wraitii, 8 years ago

Attached patch changes m_ComponentsByTypeId toan entitymap, reducing overhead in PostMessage and Broadcast message by about 50%. However this requires splitting the entitymap in two as otherwise local entities with ID 229+X would make the entity map vector ridiculous.

by wraitii, 8 years ago

Fix bit operation

by wraitii, 8 years ago

Version using an extension of EntityMap?

by wraitii, 8 years ago

Tame the monster

comment:2 by wraitii, 8 years ago

I'm pretty sure I forgot to change the serialization struct for GlobalEntityMap but otherwise this patch should work, doesn't change the checksum, passes all test including the new ones.

by wraitii, 8 years ago

RC

comment:3 by wraitii, 8 years ago

Version 4 attached here does the same but extends it to the m_ComponentCaches and m_ComponentsByInterface, which was boost::unordered_map previously. The patch is rather large but is mostly semantics change where necessary.

The only actual big changes are in EntityMap.h, where I add a few functionalities to EntityMap, and create a GlobalEntityMap that internally uses two Entitymap, one for local entities and one for regular entities.

Also included is a test file for Entity Map. Other tests are not affected by this patch. The game state is not affected at all by this patch.

I have tested SP serialization and it works.

Performance wise I ran a test for the first 2K turns of a game and the overhead associated with LookupEntityHandle and sending message seems to have been drastically reduced (by around 70/80%), I expect this to only get better with more messages and more entities.

Last edited 8 years ago by wraitii (previous) (diff)

by wraitii, 8 years ago

Attachment: messageChangesV0.patch added

comment:4 by wraitii, 8 years ago

Very WIP patch about on demand subscription to other entities. There are weird errors in the tests with my postmessage implementation, not sure why.

Needs to be tested and profiled thoroughly.

comment:5 by Imarok, 8 years ago

Keywords: rfc added; review removed

comment:6 by elexis, 8 years ago

Milestone: Alpha 21Backlog

Backlogging due to lack of progress.

comment:7 by wraitii, 7 years ago

Milestone: BacklogAlpha 22

Working on this a little more.

I've created a profiler for just the messages, which can be used in combination with profiler2 to get some more precise profiling on messages:https://github.com/wraitii/0ad/commits/simProfiler

It seems to be there is a raw overhead of about 30% to getting the messages to the right people, but my above patch didn't really reduce that substantially so we'll have to try something else. I also don't count the overhead to actually get to the HandleMessage function, which is quite high for C++->JS files.

That being said, I've discovered AiProxy takes a non-trivial amount of time, mostly because it listens to PositionChanged. In MP games, it should be disabled: the following branch has a patch that does this: https://github.com/wraitii/0ad/commits/AiProxyOptim Based on my calculations, it could save up to 10ms per turn in MP games with no AIs. This is slightly hacky and doesn't account for deserialization yet, but it should be relatively easy to fix for that.

I've also run some more profiling, and we should focus on: -Implementing more dynamic subscriptions (possibly subscribing to entities as I began above). Components such as "Guard" would benefit from this a lot, and would save several ms when calls to OwnerShip Changed occur. -Review MotionChanged messages, which are c++ -> UnitAI. Those are a big perf impact and may not be that needed

by wraitii, 7 years ago

Attachment: AiProxyOptim.patch added

git patch for the above branch

comment:8 by wraitii, 7 years ago

Resolution: invalid
Status: newclosed

Closing as invalid. I have done new, better profiling using some custom changes (see my github branches) and it turns out messages are really slow but that's not really because of the message overhead. I mean it does play a small role, but we probably should spend time elsewhere first. Patches above were annoyingly broken.

comment:9 by elexis, 7 years ago

Keywords: rfc performance removed
Milestone: Alpha 22
Note: See TracTickets for help on using tickets.