Task queueing best practices
I'm making an in-editor tool which will frequently need to perform large processing tasks. I'd like to do them asynchronously on a separate thread (or threads), to keep the editor as responsive as possible. My assumption is that the task system is best for this, particularly since the beginning and end bits of each process do need to execute on the GameThread.
asked Oct 06 '14 at 10:58 AM in C++ Programming
The Task Graph system works best for small units of work that finish very quickly. For larger, long running tasks - especially tasks spanning several frames - you're probably better off spawning a separate worker thread using the FRunnableThread API.
The number of task graph threads created depends on a number of factors, most importantly the number of available CPU cores. You can find the current logic for this in the FTaskGraphImplementation constructor. Adding your own task graph thread probably doesn't make much sense, since we already try to spawn the optimal number of threads.
If you schedule a long running task on the GameThread, then yes, it will block the game's/Editor's responsiveness. In fact, no work will be done in the game/Editor until your task has completed, and no user interaction will be possible. This is generally not desirable. If you schedule a long running task on a non-Game thread, then it will, too, block whichever thread it was scheduled to. DontCompleteUntil() will also block the task's completion until some event happened. No other tasks will be executed until the current task has completed.
To sum it up, we do not recommend the task graph for long running tasks. Use a separate OS thread using FRunnableThread to perform the work instead. You can regularly check on the game thread, i.e. in Tick(), whether this thread completed. If you have to regularly execute work on such a separate thread, it may also be a good idea to not recreate the thread each time, but instead leave it running and have it Sleep() when there is no work. You can use a work queue (TQueue) in combination with an event (FEvent) to wake up the thread and perform work. There are some examples of this in the code base, i.e. FMessageRouter::Run().
answered Oct 06 '14 at 05:52 PM
Follow this question
Once you sign in you will be able to subscribe for any updates here