Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

RaycastCommand is somehow faster in editor?

Discussion in 'Entity Component System' started by OFFICIAL_bryanw, Aug 2, 2018.

  1. OFFICIAL_bryanw

    OFFICIAL_bryanw

    Joined:
    Jul 6, 2018
    Posts:
    36
    Hey All,

    I've created a scene with some terrain and I am casting 1000000 rays in random directions to profile RaycastCommand performance on different machines.

    For some reason I am finding that the performance in editor is almost 2x that of a deployed build? Code below:

    Code (CSharp):
    1. using UnityEngine;
    2. using Unity.Collections;
    3. using Unity.Jobs;
    4. using System.Diagnostics;
    5. using TMPro;
    6. using System.Collections.Generic;
    7. using System.Linq;
    8.  
    9. public class RaycastTester : MonoBehaviour
    10. {
    11.     private int N_Rays = 1000000;
    12.     private int trials = 0;
    13.     private NativeArray<RaycastCommand> Ray_Commands;
    14.     private NativeArray<RaycastHit> Cast_Results;
    15.     private TextMeshPro my_text;
    16.     private List<long> trial_times;
    17.  
    18.     void Start ()
    19.     {
    20.  
    21.         RaycastCommand[] mCommands = new RaycastCommand[N_Rays];
    22.         for (int i = 0; i < N_Rays; ++i)
    23.         {
    24.             Vector3 this_direction = Random.onUnitSphere;
    25.             mCommands[i] = new RaycastCommand(Vector3.zero, this_direction.normalized, 250);
    26.         }
    27.         Ray_Commands = new NativeArray<RaycastCommand>(mCommands, Allocator.Persistent);
    28.         Cast_Results = new NativeArray<RaycastHit>(N_Rays, Allocator.Persistent);
    29.  
    30.         TextMeshPro[] tmpro = Object.FindObjectsOfType<TextMeshPro>();
    31.         my_text = tmpro[0];
    32.  
    33.         trial_times = new List<long>(100);
    34.     }
    35.  
    36.     private void OnApplicationQuit()
    37.     {
    38.         Ray_Commands.Dispose();
    39.         Cast_Results.Dispose();
    40.     }
    41.  
    42.     void Update ()
    43.     {
    44.         Stopwatch st = new Stopwatch();
    45.         st.Start();
    46.  
    47.         JobHandle Cast_Job = RaycastCommand.ScheduleBatch(Ray_Commands, Cast_Results, 1);
    48.         Cast_Job.Complete();
    49.  
    50.         st.Stop();
    51.  
    52.         trial_times.Add(st.ElapsedMilliseconds);
    53.         ++trials;
    54.  
    55.         my_text.SetText(string.Format("{0} ms", Mathf.Round((float)trial_times.Average())));
    56.  
    57.     }
    58. }
    59.  
     
  2. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    One thing is your test is invalid because your raycasts are randomized. Combine that with you are testing averages and over time.

    Basically you are introducing variation per run, plus the averaging method is bluring it all. So while 2x seems unlikely, it's still possible your testing methodology accounts for most of the difference.
     
  3. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    This could also be scheduling related. Try putting JobHandle.ScheduleBatchJobs before you complete. Not sure if that's actually done automatically for raycast jobs or not but would be interesting to see if it has an impact.

    Also get rid of your averaging and just spit out the current time taken. It could also be other things running are impacting the times and the averaging doesn't let you correlate what is happening in that frame from other frames.

    Using the profiler should show something about why things are different.
     
  4. OFFICIAL_bryanw

    OFFICIAL_bryanw

    Joined:
    Jul 6, 2018
    Posts:
    36
    I've taken your input and updated the vectors to be deterministic. I also am now displaying the raycasts live. Below is the modified code:

    Code (CSharp):
    1. using UnityEngine;
    2. using Unity.Collections;
    3. using Unity.Jobs;
    4. using System.Diagnostics;
    5. using TMPro;
    6. using System.Collections.Generic;
    7. using System.Linq;
    8.  
    9. public class RaycastTester : MonoBehaviour
    10. {
    11.     private int N_Rays = 1000000;
    12.     private int trials = 0;
    13.     private NativeArray<RaycastCommand> Ray_Commands;
    14.     private NativeArray<RaycastHit> Cast_Results;
    15.     private TextMeshPro my_text;
    16.     private List<long> trial_times;
    17.     private Stopwatch st;
    18.     private JobHandle Cast_Job;
    19.  
    20.     void Start ()
    21.     {
    22.         st = new Stopwatch();
    23.  
    24.         RaycastCommand[] mCommands = new RaycastCommand[N_Rays];
    25.         for (int i = 0; i < N_Rays; ++i)
    26.         {
    27.             Vector3 this_direction = new Vector3(i - N_Rays, N_Rays - i, i);
    28.             mCommands[i] = new RaycastCommand(Vector3.zero, this_direction.normalized, 250);
    29.         }
    30.         Ray_Commands = new NativeArray<RaycastCommand>(mCommands, Allocator.Persistent);
    31.         Cast_Results = new NativeArray<RaycastHit>(N_Rays, Allocator.Persistent);
    32.  
    33.         TextMeshPro[] tmpro = Object.FindObjectsOfType<TextMeshPro>();
    34.         my_text = tmpro[0];
    35.  
    36.         trial_times = new List<long>(50);
    37.     }
    38.  
    39.     private void OnApplicationQuit()
    40.     {
    41.         Ray_Commands.Dispose();
    42.         Cast_Results.Dispose();
    43.     }
    44.  
    45.     void Update ()
    46.     {
    47.         st.Reset();
    48.         st.Start();
    49.  
    50.         Cast_Job = RaycastCommand.ScheduleBatch(Ray_Commands, Cast_Results, 1);
    51.         JobHandle.ScheduleBatchedJobs();
    52.         Cast_Job.Complete();
    53.  
    54.         st.Stop();
    55.  
    56.         if (trials < 50)
    57.         {
    58.             trial_times.Add(st.ElapsedMilliseconds);
    59.             ++trials;
    60.         }
    61.  
    62.         // my_text.SetText(string.Format("{0} ms", Mathf.Round((float)trial_times.Average())));
    63.         my_text.SetText(string.Format("{0} ms", st.ElapsedMilliseconds));
    64.  
    65.  
    66.     }
    67. }
    68.  
     
  5. OFFICIAL_bryanw

    OFFICIAL_bryanw

    Joined:
    Jul 6, 2018
    Posts:
    36
    Somehow I still get the same results, and strangely enough if I do something like open up slither.io while the profiler is running (to try and task the system more), I get marginally improved performance (230ms vs 270ms), and then when I close slither.io, the performance returns back to when my system is idle...
     
  6. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    Strange. My gut reaction is differences in scheduling/completion rather then actual time in raycasting. But there isn't really a way to time the actual raycasting. Or maybe it's using burst in some limited fashion internally, enough to give it an edge in the editor?
     
  7. OFFICIAL_bryanw

    OFFICIAL_bryanw

    Joined:
    Jul 6, 2018
    Posts:
    36
    Yeah, one detail I left out is that sometimes the editor will have the same performance as a deployed build, depending on the run...

    I've looked at the profiler during both of these instances and the output to my game is the same as what the profiler reports in either case...

    The scene is just a bunch of terrain features and there are no physics objects or anything. The memory profile seems to be the same for either case too...
     
  8. julian-moschuering

    julian-moschuering

    Joined:
    Apr 15, 2014
    Posts:
    529
    Hm, 2018.2 has support for Burst in standalone builds. @snacktime, which version are you using?
     
  9. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,160
    Maybe you're CPU is just load scaling. When benchmarking, try turning that off. On windows, go to your Advanced power options and change the minimum and maximum processor state to 100% for the duration of the test.
     
  10. OFFICIAL_bryanw

    OFFICIAL_bryanw

    Joined:
    Jul 6, 2018
    Posts:
    36
    Hmm.. I just checked and then confirmed that I am always running at 100% processor state.. Good idea though!