Search Unity

Is it normal that EntityCommandBuffer.playback takes 10~30x times of the jobs?

Discussion in 'Data Oriented Technology Stack' started by TMPxyz, Jul 16, 2019.

  1. TMPxyz

    TMPxyz

    Joined:
    Jul 20, 2012
    Posts:
    765
    Hi, I'm trying to optimize by adding "dirty" tag to modified entities, if I understand it right, they will be org-ed into an archetype and so that I could loop on those dirty data in chunks.

    And here I'm having some serious performance problems.
    1. SysModData is a system responsible to loop through entities generated from input cmds, and mark modified entity with "dirty" tag.
    It takes 13ms for this sys to run, but then it takes 350ms for EntityCommandBuffer.playback to finish.
    (It's estimated that there might be 25K ~ 30K "dirty" tags to be added, and 250K input-Item entity be destroyed)

    EntityCommandBuffer.png

    2. SysUpdateAtt would loop through the dirty entities, process them and remove the dirty tags.
    The system jobs takes around 16ms, and the EntityCommandBuffer.playback takes around 130ms

    EntityCommandBuffer1.png


    So my question is:

    • Is it normal that EntityCommandBuffer takes so much time for such number of structural change?
    • I read that the "jobIndex" parameter passed to CommandBuffer could impact the performance, how can I detect if that happens?
     
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    436
    That's a known issue, as playback has to operate on Entities one by one doing structural changes. Use batch API to make changes where possible. That should be pretty straightforward for at least destroying your input Entities.
     
    TMPxyz likes this.
  3. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    1,668
    Tagging is fine if the tags are long lived (a few seconds) and limited to the number per frame but what you're seeing here is why it isn't feasible as you scale. To scale you need to avoid frequent structural changes, anything more than few 1000 per frame becomes a huge performance problem.

    Instead you need to look at some of the following.

    1. batch APIs
    2. polling components (it's very fast to simple check if (!component.bool) return)
    3. short lived entity events (i wrote a system a while ago that was popular, it's about 10x faster than entity command buffer for what it does https://forum.unity.com/threads/batch-entitycommandbuffer.593569/)
     
    TMPxyz likes this.