- Home /
Accessing Time.DeltaTime inside scheduled Unity Job
I am trying to test job completion time within a system.
using Unity.Entities;
using UnityEngine;
[DisableAutoCreation]
public class SubSystemOne : SystemBase
{
float timer = 0f;
protected override void OnCreate()
{
EntityManager.CreateEntity(ComponentType.ReadWrite<TestValueOne>());
}
protected override void OnUpdate()
{
Entities.ForEach((ref TestValueOne one) => {
for (int i = 0; i < 10000; i++)
{
//Throws an error if I schedule
timer += Time.DeltaTime;
}
}).Schedule();
Debug.Log(timer);
World.GetExistingSystem<SimulationSystemGroup>()
.RemoveSystemFromUpdateList(World.GetExistingSystem<SubSystemOne>());
}
}
public struct TestValueOne : IComponentData
{
public float Value;
}
This works fine if I just run the job. However, if I try to schedule it, I get an error. The error is because I am trying to access a reference value inside the scheduled job, which is understandable...
I have tried querying for the WorldTime component that exists by default in the World, but this does not seem to work...
I am wondering how best to proceed with completing a test like this. I am trying to set up multiple scheduled jobs to see their results. Maybe there is a better way to approach this kind of testing?
Answer by Bunny83 · Jan 24, 2021 at 12:21 PM
Regardless of the fact that Time.deltaTime can only be accessed from the main thread, it makes absolutely no sense to do so unless you need a recent value for calculations on each object. The way you use it in your example code makes no sense. DeltaTime is the time between two frames on the main thread. You accumulate that time 10000 times, every object. What do you think this value would tell you in the end?
I haven't used ECS or the Job system yet, however if you want to measure time you probably should simply use the normal System.DateTime class to get the realtime. To see how long a certain process takes, you should just get the time when it's started and once again when it's finished. The difference between the two tells you how long it took. Though I'm not sure if that makes any sense with the Job system.
When looking at this you probably want to use OnStartRunning and OnStopRunning to measure time.
Thank you for the reply.
Because the job is scheduled, it will technically execute over multiple frames, correct? As it is not tied up on the main thread....
That is what I was assu$$anonymous$$g anyway. The idea was to use Time.DeltaTime to track how long the job took to complete. With that, I was gonna track completion time on multiple jobs running at the same time.
This may be something that is easily observed using the Profiler... $$anonymous$$aybe I will consider that.
Answer by andrew-lukasik · Jan 25, 2021 at 10:46 AM
Q:
I am trying to test job completion time within a system.
A:
protected override void OnUpdate ()
{
int numRepeats = 100000;
var watch_1 = System.Diagnostics.Stopwatch.StartNew();
Job
.WithCode( () =>
{
float4 value = new float4{ x=2 , y=2 , z=2 , w=2 };
for( int i=0; i<numRepeats ; i++ )
value = math.pow( value , i );
} )
.WithoutBurst().Run();
UnityEngine.Debug.Log($"(NO BURST) Test code took {watch_1.Elapsed.TotalMilliseconds} [ms] to execute");
var watch_2 = System.Diagnostics.Stopwatch.StartNew();
Job
.WithCode( () =>
{
float4 value = new float4{ x=2 , y=2 , z=2 , w=2 };
for( int i=0; i<numRepeats ; i++ )
value = math.pow( value , i );
} )
.WithBurst().Run();
UnityEngine.Debug.Log($"(WITH BURST) Test code took {watch_2.Elapsed.TotalMilliseconds} [ms] to execute");
Enabled = false;
}
Note: Profiler window prints all the scheduling and timing details you need.
Your answer
Follow this Question
Related Questions
[ECS] Create Entities from Job ( IJobForEachWithEntity) using an EntityCommandBuffer 1 Answer
Best way to get data from a Monobheaviour in a JobComponentSystem? 2 Answers
[ECS] DefaultWorldInitialization.Initialize take 50MB 1 Answer
Unity (ECS & DOTS) Entity Sinking 0 Answers
How to create realistic wire 0 Answers