Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scheduling tasks with high priority after-the-fact #77

Open
baldurk opened this issue Nov 14, 2022 · 5 comments
Open

Scheduling tasks with high priority after-the-fact #77

baldurk opened this issue Nov 14, 2022 · 5 comments
Assignees

Comments

@baldurk
Copy link

baldurk commented Nov 14, 2022

This may be out of scope for the library, or potentially I've missed a way to do it. What I would like to be able to do is add a number of tasks with no particular priority and have them be scheduled in parallel in no particular order, but I would want the ability to immediately run one if I discover that it's particularly needed soon (while allowing others to still be scheduled as/when).

The sketched idea is to have the main thread push tasks for a bunch of deferred operations as it's processing something, but then if the results of one of those deferred operations is needed it wants to either immediately run that task on the main thread or spinloop if it's already been scheduled. The tasks can come in any order so you could push 100 different tasks and then want the results from number 50 before continuing, so waiting for 1-49 would not be ideal as then the main thread can't continue processing in parallel with them.

As far as I can tell unless I'm misunderstanding the code, WaitForTask does not prioritise the task you pass in to wait on but it looks at all tasks at equal priority. I don't see a way to elevate the priority of a task after it has been created either. I also wondered if the way to solve this would be to add a new task with a dependency on the one I want to run, but at least from a layperson's eye that doesn't seem like it would change the scheduling order.

Is there a way to do this, and/or is it something you'd be interested in supporting? In principle this could be refactored such that there is no main thread needing to sync, and everything including its processing becomes task-based so this translates into dependency management, but that's further than I'd want to go.

@dougbinks dougbinks self-assigned this Nov 14, 2022
@dougbinks
Copy link
Owner

I'll have a think about this, but the following is how I would manage it with the current scheduler:

  1. Add an atomic int flag to the task data to allow the task to be 'discarded' - i.e. in the ExecuteRange function it exits when this is set.
  2. To change a task priority cancel the old task and launch a new one.

WaitForTask can be made to prioritise tasks above a certain priority by setting the priorityOfLowestToRun_ parameter to that priority. So you could launch all tasks at a low priority, and when you need a result use the above approach to boost to the highest priority then use WaitForTask with priorityOfLowestToRun_ set to that.

@baldurk
Copy link
Author

baldurk commented Nov 14, 2022

That's a good idea, that should work for what I want - I had thought about using priorities wait WaitForTask but didn't think about a cancel+re-execute approach.

@dougbinks
Copy link
Owner

If you can keep track of any work done you can also only process what's needed in the new task, but it might be simpler just to discard it depending on what you're doing.

@dougbinks
Copy link
Owner

I can think of a way to do this in enkiTS, with a little extra work. Elevating a tasks priority would be fairly expensive, but it could be done. The work the threads are already doing cannot currently be interrupted, so this wouldn't guarantee that it would get processed immediately but it would be able to move it to the front of all other tasks or subtasks (the internal unit of work) which had not yet started processing. I'll think a bit more before committing to writing any code and get back to you.

@baldurk
Copy link
Author

baldurk commented Nov 14, 2022

That totally makes sense, it's co-operative rather than pre-emptive after all. I was only after an "as soon as possible" scheduling rather than immediate. For my part though I think your suggestion of cancelling and re-queuing with high priority is sufficient, so if this would be expensive or awkward to implement then feel free to close.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants