Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved Signaling a system in a performant way

Discussion in 'DOTS Dev Blitz Day 2022 - Q&A' started by Rupture13, Dec 8, 2022.

  1. Rupture13

    Rupture13

    Joined:
    Apr 12, 2016
    Posts:
    129
    I have a situation where I have a producer system that creates signals that later get picked up by a consumer system. These signals contain some data that the consumer system uses for its execution.

    I currently see two good ways of doing this:
    1. The producer system creates signal entities, that get picked up by the consumer system. These signal entities contain the required data in a component. The consumer system processes the signal entities in a job going over the entities (like Entities.ForEach, or the new foreach).

    2. The producer system accesses a persistent NativeContainer (like a NativeList), and adds the signals as structs into this container. The consumer system then loops over the signals container in a job (like Job.WithCode).
    It seems to me that the second solution would be better for performance, as it does not require any cost of structural changes (entity creation, deletion). I also assume that looping over the elements of a nativecontainer is faster than the foreach looping over entities, but I might be wrong there.

    My question here is which of these solutions would be better, and what the considerations for both solutions are.
     
  2. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,105
  3. kevinmv

    kevinmv

    Unity Technologies

    Joined:
    Nov 15, 2018
    Posts:
    51
    In isolation, producing the data you need directly into a container and then consuming that container in another job will have the least overhead. It _sounds_ like you are just using entities as an index for the data produced and then consumed by another system, if so then the creation of entities will add some more overhead than if you used a NativeContainer directly. As well, getting component data from chunk memory itself needs to be looked up so there is some overhead there as well before we can start iterating over each entity's component data. However if you intend to use the entities for other queries and/or data mapping outside of this producer consumer scenario then you might still want to do the first option.

    If you create all entities at once in the producer system, the components you want to write into / produce for each entity will all be contiguous just like if you used a NativeList, with the exception that entities in chunk memory are segregated in 128 entities at a time. If you have thousands of items/entities you are hoping to produce, you will see some overhead from walking ECS chunk memory compared to a completely contiguous native allocation that you'd get with NativeList/NativeArray etc...

    As always, when in doubt profile to know for sure :)

    Hope this helps!
     
    PanMadzior and Rupture13 like this.