Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Need help understanding ECB performance

Discussion in 'Entity Component System' started by slims, Apr 25, 2022.

  1. slims

    slims

    Joined:
    Dec 31, 2013
    Posts:
    86
    Having a weird performance issue where the Entity Command Buffer that runs after the bulk of my systems is taking up 11ms of time despite very little apparent usage of it.

    upload_2022-4-24_22-44-16.png

    In this screenshot, you can see the EndSimulationEntityCommandBuffer system taking up a whopping 11.26 ms. What is strange is if I turn off either PowerGridDistributionSystem or ConnectorEndsDisplaySystem, it goes down to essentially 0.

    But here's the thing: neither of these systems even use any ECB's at all, so how could turning them off so drastically reduce the EndSimulationEntityCommandBuffer performance? (also worth pointing out in this test case, I'm taking care not to use the EndSimulationEntityCommandBuffer very much at all in all the rest of my systems (also worth noting I'm not calling .Run() or .Complete() on any dependency handles in this system group)).

    There's probably way too much code to potentially look at here for the forums -- I'm really just looking for some general hint or information about how ECB's interact with systems generally that might cause this sort of behavior. Happy to paste code if needed though.
     
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,984
    Use the timeline view of the profiler. It will bring you much more clarity.
     
    Occuros likes this.
  3. Chris-Herold

    Chris-Herold

    Joined:
    Nov 14, 2011
    Posts:
    115
    "if I turn off either PowerGridDistributionSystem or ConnectorEndsDisplaySystem, it goes down to essentially 0"

    That means your command buffer system is waiting on other jobs to finish.
    You should be able to see this is in the normal CPU profiler.
    Find the command buffer system there, expand it and you'll probably see it is waiting for these other jobs.

    The numbers displayed in the entities debugger are somewhat misleading because of this.
    The timings accumulate in the systems that force a sync point.
     
    slims and Anthiese like this.
  4. slims

    slims

    Joined:
    Dec 31, 2013
    Posts:
    86
    You're right:

    upload_2022-4-25_8-16-5.png

    I guess I'm confused about the entity debugger then. Why would it accumulate the time spent in the PowerGridDistributionSystem and report it as time spent on the ECB?

    I'm still on Entities .17, is this improved at all in .50?
     
  5. Chris-Herold

    Chris-Herold

    Joined:
    Nov 14, 2011
    Posts:
    115
    I've only tested it briefly, but the behaviour seems unchanged in 0.50.
    My guess is the entire Entity Debugger will be replaced with something else.

    The problem kind of makes sense, but it's not unfixable imho.
    The timings just need to be attributed to the system that launched the jobs, instead of the next sync point, but for some reason that is not happening.
     
  6. slims

    slims

    Joined:
    Dec 31, 2013
    Posts:
    86
    Appreciate the help @Chris-Herold. Once I was able to identify that system as long running, the performance issue was super obvious.

    In the test map where I found this performance issue, this system iterates over around 10,000 entities, and for each entity, I was allocating some memory for 2 small NativeHashMaps and then disposing them. This was a silly mistake, as there is no reason to keep allocating and disposing the memory for each entity. I can just allocate once and pass those maps into the job and clear in each iteration instead. Once I did this, the job went down to about .3ms from 11ms, which is much more reasonable (although I think I can optimize it further still...).

    The two maps were only about 700bytes each, no resizing. Goes to show how bad lots of memory allocation and deallocation is.
     
    apkdev likes this.
  7. runner78

    runner78

    Joined:
    Mar 14, 2015
    Posts:
    760
    It was probably also due to Unity safety checks in the editor, I think the performance would be much better without or in builds. Also any reallocation if the capacity is not sufficient can lead to performance problems, which is why you should specify the capacity for dynamic containers. (This also applies to C# List and Dictionary)
     
  8. slims

    slims

    Joined:
    Dec 31, 2013
    Posts:
    86
    The performance of this was more or less the same in a release build. Safety checks didn't seem to affect performance much in this case. Also I was setting the capacity of these maps, they weren't getting resized as far as I can tell.
     
  9. elliotc-unity

    elliotc-unity

    Unity Technologies

    Joined:
    Nov 5, 2015
    Posts:
    228
    I'm not sure about this; you could kind of apportion blame to the sync point system for being a sync point, and if you could do enough useful work on the main thread before that, the sync point system wouldn't need to wait so long. I'd say basically that attributing a single number to a system is never going to give you a full picture of your performance when jobs are involved.

    Given that fact, I imagine it'd be somewhat difficult to improve on a simple timer that starts at the beginning of a system's main thread update and ends when it ends. It is at least clearly reporting an understandable quantity.

    Even if you could count up all the time taken up by all the jobs scheduled by a given system (and it's not super obvious to me that that would be easy or cheap in general), the actual impact of that on a game's framerate significantly depends on how many distinct jobs were scheduled, the job scheduling overhead of that, whether the jobs were able to start immediately or themselves had to wait for dependencies from earlier systems, and whether they were able to run in parallel with each other or with another non-sync-point main thread system.

    And for all that you really need to look at a profile anyway.
     
  10. Chris-Herold

    Chris-Herold

    Joined:
    Nov 14, 2011
    Posts:
    115
    No disagreement there.
    But i've seen many people confused by the numbers in Entity Debugger because of how they end up in systems waiting for job handles. Just saying, it would be nice if this weren't so, or more clearly communicated what's going on.