Post by Admin on Jul 16, 2016 4:46:45 GMT
Maxim Zaks @mzaks Dec 20 2015 18:59
I think the easiest way is to think about it as following.
A pool is like a table, where a components are columns and entities are rows.
This implies that if you have an entity which has only three components and you have 20 component types, the entity (row) has lots of empty spaces. As an empty space in our case is = 8byte (a pointer on 64bit architecture) we waste 136 bytes (17 empty spaces in an array) on this entity.
Multiple pools means different tables and therefor different columns. You have to define which component is defined on which pool by setting an attribute
github.com/sschmid/Entitas-CSharp/blob/develop/Entitas.CodeGenerator/Entitas.CodeGenerator/Attributes/PoolAttribute.cs
As you can see it is also possible to set "AllowMultiple" pools. Meaning that you will have the same column name in different tables (if we want to use the table metaphor)
Now if you know that some components are logically disjoint and and want appear on the same entity it is desirable to create multiple pools to avoid wasting memory.
As I mentioned to @strich before this technic should also have and improvement on data locality and cache misses (however this is purely philosophical I did not measured it)
And a third case where you might consider using multiple pools( maybe even from the same type) is if you want to go multi threaded. Entitas itself is not thread safe, however if you use pool per thread you should be fine. I would recommend to use also special pools for synching cross threads. e.g. PoolA is where thread A writes in and ThreadB, C read from . PoolB is where ThreadB writes to and ThreadA, C read from and so on.
Simon Schmid @sschmid Dec 20 2015 20:50
@derkork To give a concrete example: I currently have a CorePool and and MetaPool. The CorePool contains all Components needed to run the actual game, the MetaPool knows everything about the player progress and things like score, collected coins etc. They don’t really share data and you can conceptionally draw a line between core and meta game. I also saw a project where they had a UiPool for UI related things only. Theoretically you could only have one single pool, but as @mzaks mentioned, you would have a bigger memory footprint per entity, since an entity reserves space for all components. In my case, I’ll never have an entity where I add meta game related components AND core game related components. So by simply having two deticated pools I can improve the memory footprint of each entity which reserve less space for only a subset of all components.
I think the easiest way is to think about it as following.
A pool is like a table, where a components are columns and entities are rows.
This implies that if you have an entity which has only three components and you have 20 component types, the entity (row) has lots of empty spaces. As an empty space in our case is = 8byte (a pointer on 64bit architecture) we waste 136 bytes (17 empty spaces in an array) on this entity.
Multiple pools means different tables and therefor different columns. You have to define which component is defined on which pool by setting an attribute
github.com/sschmid/Entitas-CSharp/blob/develop/Entitas.CodeGenerator/Entitas.CodeGenerator/Attributes/PoolAttribute.cs
As you can see it is also possible to set "AllowMultiple" pools. Meaning that you will have the same column name in different tables (if we want to use the table metaphor)
Now if you know that some components are logically disjoint and and want appear on the same entity it is desirable to create multiple pools to avoid wasting memory.
As I mentioned to @strich before this technic should also have and improvement on data locality and cache misses (however this is purely philosophical I did not measured it)
And a third case where you might consider using multiple pools( maybe even from the same type) is if you want to go multi threaded. Entitas itself is not thread safe, however if you use pool per thread you should be fine. I would recommend to use also special pools for synching cross threads. e.g. PoolA is where thread A writes in and ThreadB, C read from . PoolB is where ThreadB writes to and ThreadA, C read from and so on.
Simon Schmid @sschmid Dec 20 2015 20:50
@derkork To give a concrete example: I currently have a CorePool and and MetaPool. The CorePool contains all Components needed to run the actual game, the MetaPool knows everything about the player progress and things like score, collected coins etc. They don’t really share data and you can conceptionally draw a line between core and meta game. I also saw a project where they had a UiPool for UI related things only. Theoretically you could only have one single pool, but as @mzaks mentioned, you would have a bigger memory footprint per entity, since an entity reserves space for all components. In my case, I’ll never have an entity where I add meta game related components AND core game related components. So by simply having two deticated pools I can improve the memory footprint of each entity which reserve less space for only a subset of all components.