Search Unity

What is the best/recommended way to reference a subset array of entities?

Discussion in 'Entity Component System' started by Mr-Mechanical, Dec 9, 2019.

  1. Mr-Mechanical

    Mr-Mechanical

    Joined:
    May 31, 2015
    Posts:
    507
    I can think of multiple ways of doing this:
    ISharedComponentData attached to the relevant subset of entities,
    OR separate entity with dynamic buffer filled with entity references,
    OR NativeArray hat has entity references inside a system

    Each method can work in this use-case... which one is the best suited/officially recommended approach?
     
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    That depends on your use case, which you have told us little to nothing about. DOTS is all about using the right tool for the job, not using some oversized swiss-army-knife. Your access patterns, algorithms, frequency of updating the subset, algorithm's relative position to a sync point, and already existing performance bottlenecks all play a role that could influence what is "best".
     
    Mr-Mechanical likes this.
  3. Mr-Mechanical

    Mr-Mechanical

    Joined:
    May 31, 2015
    Posts:
    507
    In my use case, I have to access the subset for processing in jobs (almost always one subset per job (accessed sequentially), however, I have another use case that compares 2 different subsets at once (with nonsequential access (accessed at random when examining the 2 subsets))). The subsets themselves never change after initialization. This is a very common pattern I find in my code. However, it is not always clear whether or not ISharedComponentData or entities with dynamics buffers or even NativeArrays are the best way of solving this problem. Hopefully that helps in terms of the specific usecases I'm referencing.

    I bet you might know more about this than I do, can you provide a bit of a breakdown of the pros/cons of subset methods for different use cases and the different factors involved you've mentioned?

    This could be very useful I keep running across stuck between the different options for creating the subsets of entities.
     
  4. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    So right there, the biggest downside to ISharedComponentData of having to create a sync point when modifying values is completely gone, while simultaneously removing a random access from this first use case.

    In addition, for your second use case, because your algorithm is subset vs subset, having all the entities packed together by subset means that while at first you'll be paying the price of random access, those cache lines will linger for a little bit and they will contain data that could be accessed in the future by the algorithm on the two subsets. So depending on your subset sizes and your target hardware's cache size, you might start getting some cache efficiency gains here too.

    So given this information, ISharedComponentData would be my choice by a large margin!

    One caveat is you want to pay attention to your chunk occupancy and what your other ISharedComponentData might be doing. If things get too sparse, you might even want to consider childing your RenderMesh and eating the cost of the TransformSystem overhead to get better chunk efficiency. Profiling will be important for that scenario.
     
    Mr-Mechanical likes this.
  5. Mr-Mechanical

    Mr-Mechanical

    Joined:
    May 31, 2015
    Posts:
    507
    Thanks for the info, this quite useful for deciding what to do in these situations. So what you're saying is with the subset vs subset situation accessing the 2 subsets with random access is better with 2 ISharedComponentData subsets than 2 DynamicBuffers (because of better cache usage)?
     
  6. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    It's better than dynamic buffers where the IBufferElementData contains an Entity reference. You ultimate have an array of entity references either way, either by dynamic buffer or by the NativeArray you will get from the EntityQuery. (And in fact you might even use both, have the ISharedComponentData and also the DynamicBuffer that only needs to be built once). But having only the entities that the algorithm cares about grouped together by ISharedComponentData is a very good thing.
     
    Deleted User and Mr-Mechanical like this.
  7. Mr-Mechanical

    Mr-Mechanical

    Joined:
    May 31, 2015
    Posts:
    507
    Thanks for the feedback. I am looking to use ISharedComponentData for this situation. Is it ok to read ISharedComponentDatas value in parallel inside a job (is this possible)? I have some additional info about the subset in the ISharedComponentData
     
  8. Guedez

    Guedez

    Joined:
    Jun 1, 2012
    Posts:
    827
    NativeArrays will inevitably always be the fastest way because no matter what, the other methods will in one way or another be filling a NativeArray to present you the results (afaik), but I Highly value things making sense even if it will cost a little bit of performance when dealing with ECS, since I am still very new and inexperienced with it.
    I'd use ISharedComponentData for the first use case, and populate a NativeArray as a cache, using said ISharedComponentData, to perform the subset vs subset comparson.

    I don't think you can even iterate through the entities associated with a ISharedComponentData without knowing fully it's contents, since they are identified by their hashes, so you inevitably will have access to the ISharedComponentData in the job dealing with it's entities
     
    Mr-Mechanical likes this.
  9. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    Unfortunately, no. You can only get the shared component index from inside the job. However, there's a simple solution since your data is static. You just have to copy the data from the shared components into chunk components on startup. You can read from chunk components inside an IJobChunk. Let me know if you need help with this.
     
    Egad_McDad and Mr-Mechanical like this.