Low Level Memory in C#/Unity?

Поділитися
Вставка
  • Опубліковано 7 лип 2024
  • Take advantage of C style memory access in C#, with a new found understanding of why it matters and how to make an impact. Depending on what you are doing you could easily see a 2500x performance improvement. (at least in memory time)
    ECS is great, but I wouldn't want to support its ever changing structure that can't support version changes and maintain code bases. Instead, I'll dive lower and get performance boosts I may not be able to get from ECS.
    Jobs and Burst are both great elements I plan to use in conjunction with this. But replace the parts of Unity that don't suit your needs. Sorry, no source availability here.
    0:00 Intro
    2:00 OOP vs Perf
    3:46 Overview
    4:25 CPU Prediction
    9:42 Spatial/Temporal
    12:52 Unity Intents & Limits
    15:45 Spatial Memory
    20:46 .NET Intents & Limits
    23:08 Unsafe
    23:52 C# Mem As-Is
    26:59 C# Mem Unsafe Fixed
    33:01 Create a Pointer
    39:03 Use a Pointer
    #unity #unity3d #gamedev #gamedevelopment #gamedeveloper

КОМЕНТАРІ • 15

  • @eugenschabenberger5772
    @eugenschabenberger5772 5 днів тому +1

    This is great, I somehow missed that this is possible. Back in the good old C days. Makes some things so much easier. Thanks.

  • @EmanX140
    @EmanX140 5 днів тому +1

    Very cool stuff! We need more)

  • @unitypro
    @unitypro 5 днів тому +1

    Interesting insights as always :)

  • @Tymon0000
    @Tymon0000 5 днів тому +1

    It would be nice to see an example with game logic and a simple benchmark comparison with DOTS.

    • @DanVioletSagmiller-xv3fs
      @DanVioletSagmiller-xv3fs 5 днів тому +2

      At present, ECS would probably be the same speed, because my current code only takes on the index a single car. I need to run a collection of these replace rigid body, and collider physics, specifically, I need to control the memory structure of the environment. And I'm not aware of a way to replace what RigidBody looks at, so I'll be recreating it. This is what I'm writing the Vigilante Racer code to do, and I will run a comparison on performance after. In FPS per car count in the same test environment most likely.

  • @DanVioletSagmiller-xv3fs
    @DanVioletSagmiller-xv3fs 2 дні тому

    Around 33:01 I failed to show how to get the thruster. The problem being that you can't do a fixed inside another fixed. The method to get a thruster from within the fixed engine pointer, is this
    AntiGravThruster* thruster = (AntiGravThruster*)(engine->Thrusters + (thrusterIndex * AntiGravThruster.Size));
    We didn't need to get a pointer, as we were already in one; making "->Thrusters" act as the thruster's pointer offset directly.

  • @Tymon0000
    @Tymon0000 5 днів тому

    Do you use CollectionsMarshal and Spans?

    • @DanVioletSagmiller-xv3fs
      @DanVioletSagmiller-xv3fs 4 дні тому +1

      I didn't figure out how to get Span and Memory to work in Unity until after this. (Kept trying to import name spaces and library references, but C# couldn't see it) Then I finally found the reference that said turn on Unsafe and it just shows up. :facepalm:
      However, this is generally how Span and Memory works, to the stack and heap. So I can still achieve all the same things. For instance:
      List numbers = new List() { 1, 2, 3, 4, 5 };
      Span numbersSpan = CollectionsMarshal.AsSpan(numbers);
      This is similar to
      fixed(int* iPtr = &numbers[0])
      where in this case I'm getting an int pointer. Incrementing an int instead of a byte, you increment by 1 and it moves the length of the type. so if iPtr is address 1000, and you say iPtr + 1, you would move to address 1004.

  • @morglod
    @morglod 2 дні тому +1

    you probably got alignment problem in EngineStruct.Thrusters because you should have +1 byte padding
    It may work slower that AntiGravThruster.Size*8 or even not work on some platforms

    • @dvsdev
      @dvsdev  19 годин тому +1

      For clarity, this example works. Its part of the code I'm actively using. Its possible I have some glitch in the memory because of it, so I'm not ruling that out.
      Can you give some more detail please?
      I'm not sure why I need a 1 byte padding on the arrays. I've needed things like that for low level external C APIs, For instance putting the buffer between data elements so it locks a 3 byte structure into 4 bytes because it was compiled that way. But I'm not aware of an actual limitation even on performance for this in C#. I'm not saying there isn't, but I haven't read anything detailing that. Only the offsets I occasionally need are for interacting with external libraries. And for me, I wrap that up under the concept of protocol.
      When reading the data from cache ram to a CPU register, I'm under the assumption that an exact byte position is used at no extra cost over a 4 or 8 byte chunk of memory. Again, this could be mistaken.
      AntiGraviThruster is only 40 bytes in size and so only 280 bytes for the thruster byte array. I'm not aware of that being an issue on any system. I believe the modern CPU/Cache RAM setup is loading 64 to 128 byte chunks into cache ram at a time, and so we would exceed a single RAM read, but it will still load the content over all. I'm generally trusting of Unity ECS's 16K chunk size, that it would work on most any hardware that Unity supports. I.e. I'm not planning to exceed 16k for a single memory block. But don't see a reason why I shouldn't go right up to 16384 bytes at a time.
      Now, I'm not an expert in this either. This is some 30 years of programming knowledge, down to bits, baud, 7400x ICs, minor assembly, and lots of managed code, but no formal education. I have a lot to learn but have done heavy studies into this. I gladly welcome more knowledge. Perhaps something in my response is incorrect, and I would love to get more detail on how I can improve my understanding. If I'm wrong, I'm wrong.

    • @morglod
      @morglod 15 годин тому +1

      @@dvsdev usually to get some data into CPU register, it should be word size (4 or 8 bytes). Otherwise OS will copy memory to a temporary buffer.
      With other things you are right. CPUs have 64bytes L0 cache, so whole object should fit inside for best performance. Also fields should be ordered in their access order, so CPU could walk with small offsets in one direction on data

    • @dvsdev
      @dvsdev  14 годин тому

      ​@@morglod So in that case, since the thrusters are 40 bytes each, and are largely self-contained (- the engine offset), I could put those in a single array of 28 thrusters. I would also move the engine data, which is just a offset for each of 7 thrusters, into an extra variable in each thruster. Going up to 52 bytes. It would take more memory, but each 64b chunk would contain that engine offset, and not need to load it from two different chunks. Thank you for this insight. I'll research this some more.

    • @morglod
      @morglod 13 годин тому +1

      @@dvsdev yep; I missed the thing that you have Size*7 bytes so there is no need in padding actually. So I was actually a bit wrong in my first comment.
      May be I missed and you said it, but this is called SOA (Structure Of Arrays). In some languages there are special decorators/codegeneration that may make from array of structures -> structure of arrays.
      array of structs:
      Object objs[10]
      structure of arrays:
      struct ObjectsChunk {
      objField1[10];
      objField2[10];
      // .. etc
      }
      I think all ECS should have codegeneration that will generate optimal structs instead of trying pack it in runtime. Thats the main problem

    • @dvsdev
      @dvsdev  8 годин тому +1

      @@morglod Agreed. everything I'm doing could likely be done faster in ECS, but the goal I'm pushing for is to cut out Unity physics and replace it with my own. By taking control of the memory in the process at the same time, I *should* get more perf out of this. And not have to worry about staying up to date on ECS API changes. This is the latest test from the current physics system. I haven't fully replaced Unity physics in it yet. ua-cam.com/video/9s2gVsEMmqk/v-deo.html - but I've still got plenty to learn and apply. Looking forward to the journey.