When to use BlobAssetRef / SharedComponent / ComponentDataFromEntity ?

Hi everyone,

I can’t quite understand which approach to use for common configuration data for the number of similar entities.

I have some amount of sphere particles that follow mesh vertices. Each particle is an entity. I have some config data (like max arrive speed or weight) for all of them. Right now I am using entities hierarchy for that. I created a parent entity that holds ParticlesRoot component with common data and accessing it from my jobs using ComponentDataForEntity.

But, I feel that this is not an appropriate way in terms of data locality and cache misses inside my jobs.

So, the very first idea is to add SharedComponent. But, the data is static, so, isn’t better to only create a BlobAssetRef once and add it to all Particles?
How BlobAssetRef influence cache misses?

If the data is static I would go with the blob solution.

Cache wise I think the behavior will be similar to what you do with your ParticulesRoot solution. The job will “cache miss” on the first call but then the data I’ll sit in cache for the remainder of the entities.

2 notes though
First for both situations this is true only if the entités processed in the chunk use the same static data. If they have different blob references or parent you may find yourself going back and forth with fetching the proper data.
This may be solved by shared component data to group you entities that share the same static data into the same chunks.

Second note the parent solution has an additional cost because you create a hierarchy. So your entity have a parent components and you parent has a child buffer (which may be quite big) and finally this will lead to have to run those entities through the parent/child transform system.

1 Like

Thank you. In my case, some number of particles share one config, and the other number shares another. So, yes, I might end up having 2 or more BlobAssetReferences.

What about the performance of creating BlobAssetReference?
In my case, I have a bunch of “agents” visualized as such particles and for them, I will create BlobAsset once.
But for the single ParticlesRoot of Player I need that each time it reaches that “agent” (aka, changes config). This happens each 5-10 seconds.
Will it perform fine compared to the approach with SharedComponents?

Your blob asset should be built only once ideally at conversion time (build time). The blob asset are made for heavy reading of static data they don’t shine in the write performance.
That being said if the change that occur is to change a blob asset reference for another one that exists it should not cost more than updating a component value. (Except if it’s in a shared component type which would trigger a structural change)

Basically blobs are made for data that need to be read often and don’t change or do so very infrequently.
Shared component data is made to group entities that use the same data to make sure they are processed all in the same batch and avoid as much cache miss as possible.

DOTS Physics systems uses blob for colliders for instance. Colliders don’t change shape their spatial representation is static.
Hybrid renderer uses shared component for materials (if I’m not mistaken) that way all entities that share the same material can be processed and sent to the GPU in the same batch avoiding to have to not only fetch data from cache to prepare the GPU buffer but also to avoid sending that data multiple times to the GPU. (Not an expert in that area so I may have misunderstood the details but I think the genaro idea still applies)

1 Like