Post by Admin on Jul 16, 2016 4:37:15 GMT
Maxim Zaks @mzaks Nov 13 2015 00:03
Honestly we don't care about the low level optimisations much ... because, well we are on Unity
Mike Action delivered a brilliant talk on the matter of the data locality
www.youtube.com/watch?v=rX0ItVEVjHc
However the main point of his talk you should know and optimise for the hardware that you are running. This is your real platform.
As Unity3D developers we deliberately outsource this task. We write C# which will than be some how translated and run on some platform.
By this we "outsourced" the low level optimisation. And made Unity3D our platform. For better or for worst.
There are lots of decisions in Entitas which are performance related. In the second half of our talk we tried to explain some of them. But the low level optimisation like, how good the level1 or level2 CPU cache footprints are, is kind of out of our hands anyways.
Adrian Papari @junkdog Nov 13 2015 00:18
But the low level optimisation like, how good the level1 or level2 CPU cache footprints are
I'm not sure what is currently up with Adam Martin's ECS for Unity3d, but he's been doing some work on memory layout: Replacing Unity3d’s core architecture: Structs
Regardless, I'd argue that benchmarks are essential, if nothing else to compare performance between releases - easy to sneak in a bottleneck by mistake.
Maxim Zaks @mzaks Nov 13 2015 00:28
I believe that structs are a bad idea in a garbage collected environment. We actually tried to make components structs and we got GC spikes when mutating entities.
We benchmark Entitas a lot. This is how we end up with code generator, pooled components and retain release cycle for entities. Those are all performance optimisation which we results of benchmarks. This is also why we don't use MonoBehaviours in any ways, even though people request it each time because it would be more convenient strategy.
Entitas is highly tested and Performance tests are also part of it
github.com/sschmid/Entitas-CSharp/tree/develop/PerformanceTests
Adrian Papari @junkdog Nov 13 2015 00:40
ah, missed the performance tests - but are the results published anywhere?
Simon Schmid @sschmid Nov 13 2015 00:41
github.com/sschmid/Entitas-CSharp/blob/develop/PerformanceTests/Program.cs#L58-L95
these are the numbers on my machine which I compare to with each release. If you want to keep track of performance changes, you have to save the result locally on your machine
I wanted to go with structs for components, but as it turned out, there are no benefits. As soon as we save them they will be moved to the heap
Simon Schmid @sschmid Nov 13 2015 00:48
I also have an unpublished stress test project where I can track performance changes from release to release, where I can identify memory usage and cpu pressure
Adrian Papari @junkdog Nov 13 2015 00:51
thanks - completely missed those too
appreciate the heads-up on structs - too bad they're soo unwieldy in C#/mono.
Felipe Alfonso @bitnenfer Nov 13 2015 00:56
I really don't know how unity's compiler maps memory or if even a dod approach would be beneficial. I am actually metioning this because in my current and previous job we work with consoles like 3ds which have limited memory and we really benefit from low level optimizations. If the c# compiler maps arrays the same way c compiler does then then moving component out of the entities and storing them in the systems would be a great performance boost
Maxim Zaks @mzaks Nov 13 2015 01:15
It could be something to research on but I am also not sure how strong it will interfere with the "Reactive" approach that we implemented. We observe entities and groups for changes and with that we can provide Reactive Systems. Putting components on systems will improve on data locality but I am not sure how the implementation of pub sub pattern (which reactive system essentially is) would be possible.
Most of the Entitas systems in a real world project become reactive system. I think this is a bit different in a standard DoD or other ECS implementations.
Mike Cann @mikecann Nov 13 2015 17:05
@sschmid thanks!
astro75 @astro75 Nov 13 2015 22:05
Problem with structs is that you can't use interfaces. It boxes because compiler needs to know the exact size of structure in bytes. The only way possible would be to store structs in typed arrays. And entities would have indexes in of structs in those arrays. But then there is another problem. Structs get copied to the stack, that may cause some overhead in performance. And we can't have pointers to structs in arrays because of GC. To simulate pointers api could give indexes but that is very error prone and ugly. Other way is to use another struct as a pointer (2 fields: array reference and index), but that would cause even more overhead. So I think classes are the only option for entity components in C# language.
Honestly we don't care about the low level optimisations much ... because, well we are on Unity
Mike Action delivered a brilliant talk on the matter of the data locality
www.youtube.com/watch?v=rX0ItVEVjHc
However the main point of his talk you should know and optimise for the hardware that you are running. This is your real platform.
As Unity3D developers we deliberately outsource this task. We write C# which will than be some how translated and run on some platform.
By this we "outsourced" the low level optimisation. And made Unity3D our platform. For better or for worst.
There are lots of decisions in Entitas which are performance related. In the second half of our talk we tried to explain some of them. But the low level optimisation like, how good the level1 or level2 CPU cache footprints are, is kind of out of our hands anyways.
Adrian Papari @junkdog Nov 13 2015 00:18
But the low level optimisation like, how good the level1 or level2 CPU cache footprints are
I'm not sure what is currently up with Adam Martin's ECS for Unity3d, but he's been doing some work on memory layout: Replacing Unity3d’s core architecture: Structs
Regardless, I'd argue that benchmarks are essential, if nothing else to compare performance between releases - easy to sneak in a bottleneck by mistake.
Maxim Zaks @mzaks Nov 13 2015 00:28
I believe that structs are a bad idea in a garbage collected environment. We actually tried to make components structs and we got GC spikes when mutating entities.
We benchmark Entitas a lot. This is how we end up with code generator, pooled components and retain release cycle for entities. Those are all performance optimisation which we results of benchmarks. This is also why we don't use MonoBehaviours in any ways, even though people request it each time because it would be more convenient strategy.
Entitas is highly tested and Performance tests are also part of it
github.com/sschmid/Entitas-CSharp/tree/develop/PerformanceTests
Adrian Papari @junkdog Nov 13 2015 00:40
ah, missed the performance tests - but are the results published anywhere?
Simon Schmid @sschmid Nov 13 2015 00:41
github.com/sschmid/Entitas-CSharp/blob/develop/PerformanceTests/Program.cs#L58-L95
these are the numbers on my machine which I compare to with each release. If you want to keep track of performance changes, you have to save the result locally on your machine
I wanted to go with structs for components, but as it turned out, there are no benefits. As soon as we save them they will be moved to the heap
Simon Schmid @sschmid Nov 13 2015 00:48
I also have an unpublished stress test project where I can track performance changes from release to release, where I can identify memory usage and cpu pressure
Adrian Papari @junkdog Nov 13 2015 00:51
thanks - completely missed those too
appreciate the heads-up on structs - too bad they're soo unwieldy in C#/mono.
Felipe Alfonso @bitnenfer Nov 13 2015 00:56
I really don't know how unity's compiler maps memory or if even a dod approach would be beneficial. I am actually metioning this because in my current and previous job we work with consoles like 3ds which have limited memory and we really benefit from low level optimizations. If the c# compiler maps arrays the same way c compiler does then then moving component out of the entities and storing them in the systems would be a great performance boost
Maxim Zaks @mzaks Nov 13 2015 01:15
It could be something to research on but I am also not sure how strong it will interfere with the "Reactive" approach that we implemented. We observe entities and groups for changes and with that we can provide Reactive Systems. Putting components on systems will improve on data locality but I am not sure how the implementation of pub sub pattern (which reactive system essentially is) would be possible.
Most of the Entitas systems in a real world project become reactive system. I think this is a bit different in a standard DoD or other ECS implementations.
Mike Cann @mikecann Nov 13 2015 17:05
@sschmid thanks!
astro75 @astro75 Nov 13 2015 22:05
Problem with structs is that you can't use interfaces. It boxes because compiler needs to know the exact size of structure in bytes. The only way possible would be to store structs in typed arrays. And entities would have indexes in of structs in those arrays. But then there is another problem. Structs get copied to the stack, that may cause some overhead in performance. And we can't have pointers to structs in arrays because of GC. To simulate pointers api could give indexes but that is very error prone and ugly. Other way is to use another struct as a pointer (2 fields: array reference and index), but that would cause even more overhead. So I think classes are the only option for entity components in C# language.