Replies: 3 comments 6 replies
-
Yet, the team is still working on it. rust-lang/wg-allocators#7 |
Beta Was this translation helpful? Give feedback.
-
I agree with the premise, and I also trust the judgement of the Our Machinery folks. However building these data-structures won't be my personal immediate short (or likely medium) term priority. Theres just too much other groundwork to lay down. The interfaces should probably be drop-in replacements for std types (or close to that), so the cost of adopting them later should be low.
If anyone wants to pick up this work, I'll happily weigh in / do code reviews. But if nobody wants to pick it up, it will likely be months before I get to it. |
Beta Was this translation helpful? Give feedback.
-
Can't this just be solved with ensuring that the correct about of capacity is allocated to prevent memory re-allocations? Then trimming down to size to free up memory, etc. |
Beta Was this translation helpful? Give feedback.
-
Bevy currently uses the stdlib's
Vec
andHashMap
types everywhere, but they are not a great fit for a realtime system that a game engine is. The main problems are:While they provide O(1) amortized complexity, worst-case is O(n). So while most pushes to a
Vec
are very cheap, the Nth will be expensive (allocation + copy of the current contents). When the array contains a large number of elements, this will result in a significant increase of the frame time compared to average, and most likely a noticeable hiccup for the player. This is why, in general, game engines should optimize for worse-case complexity: avoiding hiccups is important, worst-case frame time should be predictable and fit into the target boundary (usually 16 or 33 ms).This is a good illustration of the problem:
The std collections do not support custom allocators. Again, worse-case performance is important for game engines and the default allocators (jemalloc included) have N-dependent worst-case complexity. Even when using upper-bound allocators, such as TLSF, you may perform up to about 200 instructions and some amount of uncached memory reads, where a couple of instructions would be enough (increasing a pointer with a scratch allocator). A very common use case in ECS is to allocate something that is only necessary for the current system run. Scratch allocator is a great fit here that is super cheap.
The solution to these problems would be to implement custom data structures and allocators, perhaps a
bevy_std
create, that would be used throughout the engine. In general, more thought should be put into use of data structures in every part of the engine, so that the best fit for the job are used.Our Machinery's blog can be a great source of inspiration, as they are also implementing a data-oriented game engine with a lot of thought put into the fundamental aspects of it, including the use of data structures.
If @cart agrees this should be implemented, it's better be done earlier, as more work will be necessary in the future to refactor existing crates to use appropriate data structures.
Beta Was this translation helpful? Give feedback.
All reactions