question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Data locality / contiguous memory

See original GitHub issue

This is an R&D issue. I’d be happy if you guys participate if you have ideas or experience in this field. The following problem is inherent to ECS architecture afaik.

History / current state / Motivation

Over time Entitas became faster and faster as I constantly optimize and profile all the features. The biggest leap in performance was to not store components in Dictionaries anymore but use Arrays instead. Component access time improved by a factor of 60x. This approach sacrifices memory in favor of speed. With the introduction of multiple pools I provided a mechanism to improve the memory footprint of entities to address this issue. Currently entities store components in an array of a fixed size. If you have 200 components, each entity that you create has an array of capacity 200 to potentially store all components. Using multiple pools and assigning components to one or more of those pools results in entities with a smaller array. E.g. you have 2 pools, each with 100 components assigned (instead of 200), an entity only has to reserve memory for 100 components instead of 200. Awesome.

Currently this array is of type IComponent[], this means it stores pointers to the components. When you have a class PositionComponent, the pointer to this object will be stored. If you create a struct PositionComponent it will be boxed because the array is of type IComponent[] and again, the pointer is stored.

This means components are all over the place in the heap. This is actually not really a problem. Entitas is battle tested on low-end mobile devices and proofed to be very efficient even with lots and lots of entities.

But since I’m striving for the best of the best performance possible it would be nice to find a solution to improve data locality / contiguous memory / CPU cache misses.

Ideas

Components as struct

This would currently not improve anything, because of boxing. Any ideas no avoid this?

Drop the array

Don’t use an array at all… Use the code generator to generate actual fields in the entity. Generate multiple Entity types based on the pool to avoid every entity having fields for all possible components.

Your suggestions (share your ideas)

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:29 (19 by maintainers)

github_iconTop GitHub Comments

1reaction
mzakscommented, May 27, 2016

I had a discussion with @jamesmintram once about the size of the entity and why we use multiple pools. He proposed something interesting. As a pointer on an 64bit arch takes 8 bytes, what if the entity would store not an array of pointers but an array of indexes which can be 1 or 2 bytes big. Now if we say components are managed by a coordinator which has an array of components pre wormed, as @arne-schroppe and @braaad suggested, than entities can ask component coordinator/manager to replace, “destroy” or give them new components, where they get only an index. Components than can be structs or classes. As the coordinator holds only particular type of component no boxing should happen. We should have an annotation, which let user define how many entities s/he intend to have in the game. If it is lower than 255 than we could even use 1byte index inside the array. 2bytes -> 65535 entities should be enough for most of the games. The annotation could be added to every component or just to the pool.

All that sad I think the most important point was mentioned by @braaad . We need a few very good tests in order to see if what we do make sense not only on “paper” but in real world scenario. Also I liked the idea of FlagComponents being just part of the bit field/mask.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Data locality / contiguous memory #112 - sschmid/Entitas
Component access time improved by a factor of 60x. This approach sacrifices memory in favor of speed. With the introduction of multiple pools...
Read more >
Locality of reference
Data locality is a typical memory reference feature of regular programs (though many irregular memory access patterns exist). It makes the hierarchical ...
Read more >
Data Locality - an overview
Data locality is a key to good performance on all modern CPU and fine-grained architectures. In many cases, loop fusion can be used...
Read more >
Memory and locality
Arrays are implemented as a sequence of consecutive memory locations. Therefore, if the indices used in successive array operations have locality, the ...
Read more >
About memory locality of a linked list
A linked list might be composed of chunks of contiguous data spread around the memory, and might still be completely allocated at cache...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found