Rewrote concurrent entity allocations to be more efficient#86
Rewrote concurrent entity allocations to be more efficient#86Ralith merged 1 commit intoRalith:masterfrom
Conversation
|
I assume that |
aae1877 to
fbfee66
Compare
|
Thanks for the PR! Will try to dig into it this week.
This was actually intended behavior. The principle is that sensible results are only guaranteed for |
0544798 to
cf26e71
Compare
Ralith
left a comment
There was a problem hiding this comment.
Did a deep dive. This looks awesome, thanks! Only cosmetic issues, AFAICT.
| let new_id_start = (base - cmp::min(range_end, 0)) as u32; | ||
|
|
||
| (new_id_start, new_id_end) | ||
| }; |
There was a problem hiding this comment.
Style nit: This would be a little more concise if Ranges were computed directly without the start/end intermediate variables. For example:
let freelist_range = range_start.max(0) as usize .. range_end.max(0) as usize;This makes several changes: - Cuts in half the number of atomic operations to reserve an Entity, and simplifies the reservation code to no longer need a retry loop. - Adds a new `reserve_entities` method that can reserve any number of Entity IDs with a single atomic subtract. - Removed the `reserved` and `free` arrays, which consumed two u32 values for every Entity ID, and replaced them with a single `pending` Vec. `pending` only needs one slot for every freed Entity. - No longer dump huge lists of fresh IDs into the freelist when we grow. The freelist only holds explicitly freed values, and we use arithmetic to acquire new IDs. - Removes the `reserved_len()`, etc. API used to flush reserved entities. Now flush() takes a closure to initialize each entity. - Tightened the restrictions on what you are allowed to do while you have unflushed reservations. - Grow meta and pending incrementally, as values are allocated and freed, rather than in a monolithic `grow` method. This turns out to make things simpler, e.g. we need to track the end of the "reserved" range of pending anyway, and using the Vec len is handy. - Adds some unit tests.
|
Thanks, I applied all of your feedback. |
|
Great stuff! |
This makes several changes:
and simplifies the reservation code to no longer need a retry loop.
reserve_entitiesmethod that can reserve any numberof Entity IDs with a single atomic subtract.
reservedandfreearrays, which consumedtwo u32 values for every Entity ID, and replaced them with a single
pendingVec.pendingonly needs one slot for every freed Entity.grow. The freelist only holds explicitly freed values, and we use
arithmetic to acquire new IDs.
reserved_len(), etc. API used to flush reservedentities. Now flush() takes a closure to initialize each entity.
have unflushed reservations.
freed, rather than in a monolithic
growmethod. This turns outto make things simpler, e.g. we need to track the end of the
"reserved" range of pending anyway, and using the Vec len is handy.