pico_headers
pico_headers copied to clipboard
3 little design questions
Hello,
I've recently discovered your project through https://github.com/abeimler/ecs_benchmark while researching different solutions and implementation ideas for entity component systems. My remarks or questions are only about the ECS.
I've rewritten (renamed, reorganised) completely pico_ecs.h
and its corresponding Test and Benchmark to accustom myself with it and also to match my own conventions, and I'm developing it in C++ on and for Windows, my compiler is x64 MSVC v19.29 with VS 16.11, so I've sadly not much code to share or commit. So far, I kept it as much C as possible, the only C++ features used are
- namespaces
- compiler attributes
- bool
I reached a point where the next modifications planned are going to diverge from the original logic. Therefore, I thought it would be a good time to ask questions and or debate on some design choices, with hopefully some enlightenments on both parts.
I'm basing myself on the last available version at the time of writing, which is commit 433f25f
1. Why are you exclusively using a prepopulated entity identifier pool ?
Entity identifiers are simple unsigned integer values that are used as indices. You are only counting down when creating a new entity. The pool is useful when some entities are deleted and new ones are created, so that those new entities re-use identifiers and therefore keep the identifiers within the bounds of arrays as they used as indices. However, in most use cases this concerns only a portion of the entities, usually a lot exist from start to finish. Wouldn't it be best to split them in two groups ? This reduces the memory because the prepopulated pool of identifiers would be smaller and improve the creating and deletion speed by a bit of others entities.
2. Why are you using stacks ?
The three variables that are of type ecs_stack_t
are entity_pool
, destroy_queue
, and remove_queue
All could be of type ecs_array_t
with the only logic modification being to count up instead of down for entity_pool
.
Both destroy_queue
, and remove_queue
are iterated in memory order in ecs_flush_destroyed
and ecs_flush_removed
which is not what how a stack is meant to work, that is: first-in last-out, last-in first-out, to my knowledge.
I suggest to use ecs_array_t
instead, it reduces the amount of code, as the type ecs_stack_t
and it's associated functions are not required.
3. Why does ecs_entity_t
have a ready
variable ?
There is no other assignment than at creation in ecs_create
. When you create an entity, you generate its identifier and set it ready
. Then it is only referred in if statements in
-
ecs_free
which destroys the ECS -
ecs_reset
which resset the ECS -
ecs_is_ready
used inecs_flush_destroyed
andecs_flush_removed
-
ecs_is_entity_ready
used in asserts
entities
contains all ecs_entity_t
, it is only iterated in ecs_reset
and ecs_free
both of which should occur in permitting state, that is not during updates, most likely only when the game starts, changes scene, and terminates. ready
is generating padding because the structure is aligned to it's highest alignment variable. Let's say I have PICO_ECS_MAX_COMPONENTS
= 135 and entity_count
= 500000, in 64bit. entities
takes 16M bytes of which 12M bytes are comp_bits
, 500K bytes are ready
, and 3.5M bytes are padding caused by ready
. This is 21.8% of padding memory, which of course varies with the value of PICO_ECS_MAX_COMPONENTS
.
The three solutions I see are
- Forcing the alignment to 1 byte, which is a bad idea because it disserves the CPU. I have not tested it but I assume it should reduce the performance
- Moving
ready
into thecomp_bits
, that requires modifying a bit howecs_bitset_t
works to take into account that one bit itready
. Maybe unions ? - Removing
ready
completely and loose a few microseconds when callingecs_reset
orecs_free
My results
Those are three of all the changes I made to increase the performance by 40 to 130% depending on what is benchmarked and still have some planned. I'm also planning on improving the tests and benchmarks.
I'm really interested in your takes, what I missed and got wrong.
Thank you
Wagi