Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Process of porting game prototype to DOTS and to what extent

Discussion in 'Burst' started by Petter_H, Jul 30, 2021.

  1. Petter_H

    Petter_H

    Joined:
    Jul 25, 2020
    Posts:
    12
    Today I wrote my first foreach job w/ Burst code plus use of RaycastCommand, on a function that does a lot of raycasts and showed up as heavy in profiling, as I've been wanting to try Burst for a long time. Some key results of this refactoring:
    • Serial execution time of actual computation about 1/100 in Burst version, i.e. crazy fast and "zero" for practical purposes. As for the job [BurstCompile] made all the difference, before that job version was slower than the original.
    • Populating necessary containers, mostly NativeArrays (TempJob allocator) is however taking a relatively long time and putting a cap on performance gains. Didn't have time to look into the details yet but I suspect this at a minimum creates a lot of random memory accesses in my conventional Unity GameObject/Component codebase that were paid for implicitly before.
    • Code length went from 100 to approximately 300 source lines, although maybe up towards 100 of those lines were caused by having to factor the update call style code into a manager update on a list of objects. At any rate, the logic will be considerably harder to modify after this code change.
    • It took me a good five hours excluding prior reading (yeah, doesn't say much without showing the code, but the point is untangling object oriented code to fit into a neat IJobParallelForTransform can be a lot of work).
    So to me, it looks like I will have to make targeted code replacements of wherever shows up hot in the profiler, but my concerns are:
    • how scalable this approach is going to be. Filling native containers is very heavy and not fun (programmer) work, and to maintain said code on any extensive functional changes wouldn't be fun either. Already noted were performance implications. So it is a natural question if that can be avoided, which leads to the next points:
    • Would it be better to go all in and start refactoring my project into ECS entities? Or am I still going to be filling native containers before jobs much? The fact is I've never seen a large scale project in ECS or extensively using the job system (I've been away from Unity for a while and returned recently), which makes the high level code architecture to make extensive use of e.g. Burst for gameplay code guesswork for me. Anyone has some favorite Git repo with a real large scale game or library that puts jobs, Burst and/or ECS to full use?
    • Something I didn't try yet: If I use persistent native containers where possible (i.e. as a form of caching) rather than generating new ones allocated by TempJob, is that likely to positively or negatively impact performance in general (due to additional cache misses vs time reconstructing)? Or is it close enough to always be a case-by-case decision? Should I generally be keeping stuff in native containers where possible even if not using ECS?
    I certainly find answers to these questions as I gain more experience with DOTS, but I know that a lot of you have already went through this process, so I thought I should reach out in case someone has a helpful opinion after using DOTS in the wild.
     
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,222
    Some of this should really be asked in the DOTS forums, but I will answer here anyways.

    Most of the data in ECS is stored natively in a Burst-friendly format. So you can operate on the data directly from jobs and build up long job chains that let the worker threads chew through.
    There's a few of them stickied in the DOTS subforum.
    Open-source games are a little harder to come by. But here's mine if you want to play with it. https://github.com/Dreaming381/lsss-wip Clone it and make a local build to see the real performance of it.
    If you can avoid copying data in and out of native containers by keeping them in persistent containers, then that's likely a huge win.