Search Unity

I'm seeing a lot of examples that create 'new' variable in ECS inner loops, isn't this bad practice?

Discussion in 'Entity Component System' started by Arowx, Jun 13, 2018.

  1. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    Basically in old school optimisation initialising or creating a variable in an inner loop is sub-optimal, every time the loop goes around the program creates a new variable. When an external to the loop variable could be used for better performance e.g:

    Code (CSharp):
    1. public void Execute(ref Postion pos)
    2. {
    3.    float3 value = position.Value;
    4.  
    5.   // do some stuff
    6. }
    Where ideally you would allocate the "float3 value" outside of the loop or in this case function and then that saves you the creation cost in the loop where it will cost you every loop.

    I know I should benchmark this, take my own advice, but thought I would put it out there to see if the old school optimisations still apply to this new Burst ECS system/technology?
     
  2. capyvara

    capyvara

    Joined:
    Mar 11, 2010
    Posts:
    80
    There's no heap allocation on struct/value variables, it will probably get mapped to a register or some place in the stack.
     
  3. Afonso-Lage

    Afonso-Lage

    Joined:
    Jul 8, 2012
    Posts:
    70
    That's why I think structs on C# should not need new keyword, because it can be confusing to many devs when it its allocated on heap vs stack.

    As long as you keep using structs, you are good to declare new variables even inside loops.

    By the way, this isn't Unity fault, its C#. Just to note.
     
    FROS7 likes this.
  4. daxiongmao

    daxiongmao

    Joined:
    Feb 2, 2016
    Posts:
    412
    I had this discussion before I don't think it's actually in the spec about where structs are placed.
    Maybe something changed in newer versions. But it also seems like most implementations do it this way though.
    So in the end maybe the same thing.
     
  5. ChrisDirkis

    ChrisDirkis

    Joined:
    Jun 1, 2017
    Posts:
    38
  6. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    So does the Burst Compiler work on IL code or does it work on C# code?
     
  7. ChrisDirkis

    ChrisDirkis

    Joined:
    Jun 1, 2017
    Posts:
    38
    Burst compiler compiles C# to IL(? probably, though I know it uses LLVM so maybe it goes straight to machine code (through LLVM's version of IL)), and either LLVM or the Mono JIT will do a lot of optimisations as it compiles to machine code.
     
  8. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    789
    Burst cannot compile C# to IL:
    1.) that's what the C# compiler is for
    2.) If they'd generate IL, then how could they possibly make use of SIMD instructions?

    Burst compiles IL to C#.
    IL is already a thing that can be easily parsed / changed / optimized for different things.
    The mono jit (and any jit around nowadays) actually doesn't do all that much optimization as people thought they did.
    Look it up on the coreFX repo. Take the major C++ compilers as an example, they are lightyears ahead of the jit compiler even though the jit-compilers were hailed as having so much more chances to do even better optimizations (and its true, but nobody really put the work in to actually make it so)
     
  9. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,618
    Watch the C# to Machine Code talk to learn how that works.

    how_burst_works.png
     
    Claytonious and optimise like this.
  10. Afonso-Lage

    Afonso-Lage

    Joined:
    Jul 8, 2012
    Posts:
    70
    At the moment, Brust compiler doesn't works with C# code, only IL generated code. But they are working on a custom Roslyn C# compiler, to have a smarter and performantic compiler focused on Unity. It's important to note that they aren't improving Roslyn C# compiler, they are specializing it on Unity, it's a important difference. That's why they are encoraging us to use that HPC# subset (no classes, no managed code, etc), because the custom C# Roslyn compiler will be capable of doing better otimizations on those subset, since it will have more context and no aliasing (or at least fewer).
     
  11. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    How would I benchmark this the ECS system is super fast so how would I tell the difference between something that would probably only make fractions of a ms different over extended time runs?