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. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

Cancel and check progress - QOL improvements for longer running tasks

Discussion in 'Entity Component System' started by Prodigga, Jul 9, 2018.

  1. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    1,121
    Hi guys

    I am using the Job system in an editor tool to crunch a bunch of data. The operation can take 2-3 minutes, versus the 45 minutes it takes without burst compilation.

    I would like the give the develop the ability to cancel the job and view its current progress.

    It would be great if I could check the progress of a task, even if approximate and not completely accurate, and an ability to cancel a task if the user changes their mind.
     
  2. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,554
    How can an arbitrary program know its own total running time automatically? O _ o
     
  3. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    1,121
    I did say progress, not runtime. I have 2 big jobs, both of them are IJobParallelFor. Basically just a lot of number crunching on large arrays. So, atleast for ParallelFor jobs, it would be sufficient to just be told how many of the elements have been processed in the job. Something is in charge of dispatching the jobs, right? So surely something somewhere is aware of how many elements remain to be processed.
     
  4. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,186
    The total number of batches needed and the number of batches started is information that could be available. The information isn't accurate, but for a progress bar, that's more than good enough to show progress.


    After all, users are used to this:

    Copying files. Time remaining:
    15 seconds
    3 minutes
    60 seconds
    3 hours
    1 hour
    25 minutes
    2 minutes
    3 seconds
    3 seconds
    3 seconds
    2 seconds
    > 1 year
    finished.
     
    pencil1 and Prodigga like this.
  5. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,554
    Ok for parallel for jobs rough progress is possible enabled by the index limit you supplied explicitly to the .Schedule, and each run is a copy of the same code. I translated progress to runtime because progress by definition would have to be computed from the current work / total work, and in programming we usually compare performance via time profiling. (other than this it would be comparing opcode, or time complexity) In a non-parallel job we could not know the current work regarding to any possible input. (an extension of halting problem?)

    Supposed that only parallel for job can compute progess, if there is a place for that it might be JobHandle, but JobHandle is also for normal IJob that's why I think they did not put this kind of specific utility on it. (But still possible manually by having some kind of bool NativeArray which each job can set for its own slot when it is done, then you could examine from outside of the job)

    For canceling the task I believe it is related to determinism. Consider this example case : an IJob which do a read/write to +1 to a ComponentDataArray<int> continuously in a long for-loop.

    After firing the job in the main thread still in the same frame, you do something else which take some time and then call the method jobHandle.Cancel(). In the line immediately afterwards you examine the CDA you could get different value each time you run this program because we don't know how many for-loop it went on the thread in that mean time.
     
  6. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    1,121
    Yeah it would be impossible to generically compute progress time, I think it would be enough to have a feature like this for ParallelFors only.

    I agree that a Progress float on the JobHandle would be gross as it is only applicable to a few types of jobs.

    Even something like ParallelFor.GetProgress(jobHandle) would be fine.

    Just anything, really.

    Can you actually do what you are suggesting with the native bool array? Arent you not supposed to touch the output arrays until the job is complete? Wouldn't this cause some sort of error?

    I mean, that's the nature of cancelling something before it's done, right? The data that was being processed should not be accessed because it is incomplete. It should be up to the dev to discard the data after a cancelation.

    Edit: I haven't used the job system with the component stuff yet, I kind of see what you mean. Because you pass in component references there is no way to "discard the data" because you are writing directly into the components.

    I don't know but I'm sure there's some nice solution. What I said still kind of stands true. If, as the developer, you allow users to cancel that specific type of job, you should understand what kind of issues it could create and so shouldn't allow jobs to be cancelled that could corrupt entity that, etc. I don't think the system has to hold our hand to that extent. It would be like if the Unity devs hid away the Destroy method because it can cause unintended and unpredictable errors. I mean, yes it can, but it doesn't mean it's not a useful function.
     
    Last edited: Jul 9, 2018
  7. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    Simplest would be the job using atomics to change an int* unsafe value on each iteration.
     
    starikcetin likes this.
  8. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    1,121
    Cool, I will give it a go tonight and report back, thanks.

    Care to share thoughts regarding cancellable jobs?

    Maybe I can have my own cancelation feature - an unsafe bool* in the job that each job checks before processing the work? If bool is ever set to false, just return out of the Execute method immediately? I'd still have to iterate over all the remaining items in the ParallelFor but I don't think that would be a huge issue.

    My primary concearns here are performance - does any of this break performance gains from Burst compilation?
     
  9. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,554
    You are right, this is impossible because of the safety system. You have to go unsafe like Joachim said.

    Because Unity is holding very strong with this 2 principles : determinism and safe, no race conditions. (https://github.com/Unity-Technologi...tation/content/scheduling_a_job_from_a_job.md) I understand that while this feature could be useful in some situations it make you unable to say the framework is 100% deterministic, and that is quite tempting to enforce the no cancel design.


    I have had the same request when I was designing a parallel searching job. When one of the found the solution there is no point for the remaining of them to continue. Seems like unsafe bool is the only solution to make other instance early exit (i.e. to communicate between jobs)
     
  10. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    No shouldn't have any negative performance impact. Of course you want to check the bool in reasonable batch sizes, if the granularity for how often you check is too small then it just adds overhead.
     
    Enrico-Monese likes this.