Search Unity

Question Synchronous Compilation Attribute flag does not work in Build.

Discussion in 'Burst' started by krubbles, May 29, 2023.

  1. krubbles

    krubbles

    Joined:
    Sep 20, 2020
    Posts:
    14
    Hi, I have a Burst Job in my game that has Synchronous Compilation set to true. It does not work if it isn't compiled under burst so it absolutely must not run as managed code. However, when I run it in a build, the first ~300 instances of the job are run as managed. How can I make it not do this?
    upload_2023-5-28_22-18-4.png
    upload_2023-5-28_22-16-50.png
    upload_2023-5-28_22-15-45.png
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    5,987
    First, please post your code and log as text, not images.

    Does it work with SynchronousCompilation set to false? Why does it need to be set? What makes your code NOT work when not compiled with Burst?
     
  3. CarpetHeadDev

    CarpetHeadDev

    Joined:
    Nov 2, 2022
    Posts:
    2
    Synchronous Compilation is an editor behaviour. In a build, compilation is all AOT. it won't have any effect. I can't think of any reason why jobs would change whether they are burst compiled or not in a build though
     
  4. krubbles

    krubbles

    Joined:
    Sep 20, 2020
    Posts:
    14
    Thats what I thought, but its seemingly running the job managed at the beginning. Those log messages are from a build. The log function only logs if its running in Mono C# instead of Burst. What I'm looking for is a way to make it behave the way you say it should.

    I have no idea why it doesn't work either. Something I'm doing breaks the equivalency between burst compiled or not, maybe an incorrectly implemented AVX emulation in C#, maybe something else, I don't know, and it would be a nightmare to find out.
     
  5. krubbles

    krubbles

    Joined:
    Sep 20, 2020
    Posts:
    14
    It does not work with Synchronous Compilation set to false until it starts running unmanaged. I don't know why, probably either a bug in Burst or me doing something that isn't guaranteed to be equivalent by the Burst compiler. That is why it needs to be set. In the editor it does compile synchronously and works, but for some reason it is calling it as managed code when I first execute it in a build. I am trying to find a way to make it not do that.
     
  6. tim_jones

    tim_jones

    Unity Technologies

    Joined:
    May 2, 2019
    Posts:
    287
    That's strange. As @CarpetHeadDev said, synchronous compilation only has an effect in the Editor. In a player build, code is either Burst-compiled or it isn't, and (should) only ever run either the Burst-compiled version or the managed version. I've not seen that before where it runs the managed version then switches to the Burst version - that shouldn't be possible.

    I'm not able to tell from the code-images you posted how the Evaluate method is called - is it called from within NoiseNodeBurstJob?
     
  7. krubbles

    krubbles

    Joined:
    Sep 20, 2020
    Posts:
    14
    Sorry I screenshotted the wrong Evaluate method! this is the relevant one:
    Code (CSharp):
    1. [BurstCompile(CompileSynchronously = true, FloatMode = FloatMode.Fast, FloatPrecision = FloatPrecision.Medium)]
    2.         public unsafe void Execute()
    3.         {
    4.             bool managed = false;
    5.             SetIfManaged(ref managed);
    6.             if (managed)
    7.                 UnityEngine.Debug.Log("Cannot run BurstNoiseNodeEval managed");
    8.             if (sampleCoords.Length > 0)
    9.             {
    10.                 for (int i = 0; i < sampleCoords.Length; i += 8)
    11.                     Evaluate(NoiseVector.Zero, i);
    12.             }
    13.             else
    14.             {
    15.                 // execution
    16.                 int index = 0;
    17.                 for (int z = zMin; z < zMax; z++)
    18.                     for (int y = yMin; y < yMax; ++y)
    19.                         for (int x = xMin; x < xMax - 7; x += 8)
    20.                         {
    21.                             Evaluate(new NoiseVector(x, y, z), index);
    22.                             index += 8;
    23.                         }
    24.             }
    25.         }
     
  8. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    5,987
    That Execute() method is in a job? Why would you have that managed check in there anyway? I mean, since the method has the BurstCompile attribute it shouldn't not run without Burst. I get the feeling that you're hunting a ghost bug, or Heisenbug, that only exists because you're testing whether it exists. ;)

    Btw, with the if conditions in there you're likely to hurt performance. Both for the if(managed) check and even more so for if (sampleCoords.Length > 0) ... you may see better performance if you perform that last check before running the job, and having two separate jobs for these separate code paths just so you don't have any conditionals in the bursted job.
     
  9. krubbles

    krubbles

    Joined:
    Sep 20, 2020
    Posts:
    14
    No, it definitely exists if I don't test for it, the output of it was completely wrong if I didn't call the Burst Code up front in a build and wait a bit before using it. I do wonder if that only happens in development builds though, so I'll have to test that.

    The conditional statement should not affect performance, I expect these jobs to usually take at least 0.1ms, and the if statement (even in the worst case where branch prediction fails) should still take <10ns. The managed check should get removed completely by the burst compiler, since SetIfManaged() gets discarded because of the [BurstDiscard] attribute and after that the if branches on the constant false.