Search Unity

Burst Compiler causes worse performance URP

Discussion in 'Entity Component System' started by RickyAvina, Jan 23, 2022.

  1. RickyAvina

    RickyAvina

    Joined:
    Jan 19, 2017
    Posts:
    4
    Hello, I am using Unity 2020.3.26f1 with the Universal Rendering Pipeline with the following packages:

    `Jobs 0.11.0-preview.6, Universal RP 10.8.1, Burst 1.5.4, Mathematics 1.2.1`


    I am using the code from this tutorial: https://www.raywenderlich.com/7880445-unity-job-system-and-burst-compiler-getting-started

    Which essentially just samples Perlin noise and calculates the position of vertices on a mesh with the following Job:
    Code (CSharp):
    1.  
    2.  
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using UnityEngine;
    6. using UnityEngine.Jobs;
    7. using Unity.Collections;
    8. using Unity.Burst;
    9. using Unity.Jobs;
    10. using System.Threading.Tasks;
    11. using Unity.Mathematics;
    12.  
    13. public class WaveGenerator : MonoBehaviour
    14. {
    15.     [Header("Wave Parameters")]
    16.     public float waveScale;
    17.     public float waveOffsetSpeed;
    18.     public float waveHeight;
    19.  
    20.     [Header("References and Prefabs")]
    21.     public MeshFilter waterMeshFilter;
    22.     private Mesh waterMesh;
    23.  
    24.     //Private Mesh Job Properties
    25.     NativeArray<Vector3> waterVertices;
    26.     NativeArray<Vector3> waterNormals;
    27.  
    28.     //Job Handles
    29.     UpdateMeshJob meshModificationJob;
    30.     JobHandle meshModificationJobHandle;
    31.  
    32.     private void Start()
    33.     {
    34.         InitialiseData();  
    35.     }
    36.  
    37.     //This is where the appropriate mesh verticies are loaded in
    38.     private void InitialiseData()
    39.     {
    40.         waterMesh = waterMeshFilter.mesh;
    41.  
    42.         //This allows Unity to make background modifications so that it can update the mesh quicker
    43.         waterMesh.MarkDynamic();
    44.  
    45.         //The verticies will be reused throughout the life of the program so the Allocator has to be set to Persistent
    46.         waterVertices = new NativeArray<Vector3>(waterMesh.vertices, Allocator.Persistent);
    47.         waterNormals = new NativeArray<Vector3>(waterMesh.normals, Allocator.Persistent);
    48.     }
    49.  
    50.     private void Update()
    51.     {
    52.         //Creating a job and assigning the variables within the Job
    53.         meshModificationJob = new UpdateMeshJob()
    54.         {
    55.             vertices = waterVertices,
    56.             normals = waterNormals,
    57.             offsetSpeed = waveOffsetSpeed,
    58.             time = Time.time,
    59.             scale = waveScale,
    60.             height = waveHeight
    61.         };
    62.  
    63.         //Setup of the job handle
    64.         meshModificationJobHandle = meshModificationJob.Schedule(waterVertices.Length, 64);
    65.     }
    66.  
    67.     private void LateUpdate()
    68.     {
    69.         //Ensuring the completion of the job
    70.         meshModificationJobHandle.Complete();
    71.  
    72.         //Set the vertices directly
    73.         waterMesh.SetVertices(meshModificationJob.vertices);
    74.        
    75.         //Most expensive
    76.         waterMesh.RecalculateNormals();
    77.     }
    78.  
    79.     private void OnDestroy()
    80.     {
    81.         // make sure to Dispose any NativeArrays when you're done
    82.         waterVertices.Dispose();
    83.         waterNormals.Dispose();
    84.     }
    85.  
    86.     [BurstCompile]
    87.     private struct UpdateMeshJob : IJobParallelFor
    88.     {
    89.         public NativeArray<Vector3> vertices;
    90.         public NativeArray<Vector3> normals;
    91.  
    92.         [ReadOnly]
    93.         public float offsetSpeed;
    94.  
    95.         [ReadOnly]
    96.         public float time;
    97.  
    98.         [ReadOnly]
    99.         public float scale;
    100.  
    101.         [ReadOnly]
    102.         public float height;
    103.  
    104.         public void Execute(int i)
    105.         {
    106.             //Vertex values are always between -1 and 1 (facing partially upwards)
    107.             if (normals[i].z > 0f)
    108.             {
    109.                 var vertex = vertices[i];
    110.  
    111.                 float noiseValue = Noise(vertex.x * scale + offsetSpeed * time, vertex.y * scale + offsetSpeed * time);
    112.  
    113.                 vertices[i] = new Vector3(vertex.x , vertex.y, noiseValue * height + 0.3f);
    114.             }
    115.         }
    116.  
    117.         private float Noise(float x, float y)
    118.         {
    119.             float2 pos = math.float2(x, y);
    120.             return noise.snoise(pos);
    121.         }
    122.     }
    123. }
    If I use the [BurstCompile] flag, I seem to get even worse FPS performance than if I take it off.
     
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    This is pretty hard to believe without visual proof. Can you show us profiler captures?
     
  3. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,709
    Safety checks on maybe?
     
  4. print_helloworld

    print_helloworld

    Joined:
    Nov 14, 2016
    Posts:
    231
    try running with less than 64 batches, maybe 1 or 2
     
  5. RickyAvina

    RickyAvina

    Joined:
    Jan 19, 2017
    Posts:
    4
    @RoughSpaghetti3211, turning safety checks off didn't increase performance, neither did using 1-2 batches @print_helloworld. @DreamingImLatios I've attached the profilers for both the No burst compiler run and the burst compiler run, and they look very similar. Is the high memory usage concerning?
     

    Attached Files:

  6. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    From your profiler captures it seems your project is running better with Burst. Your peak frame times stay under 66 ms with Burst and the blue area for scripts without Burst seems to disappear with Burst.
     
  7. Shinyclef

    Shinyclef

    Joined:
    Nov 20, 2013
    Posts:
    505
    Are you running in burst even for the first frame your job runs? Or is it compiling asynchronously? Try turning on synchronous compilation. If that helps you can use the compile synchronously attribute on your job if that's preferable.