![]() |
ezEngine
Release 25.03
|
This system allows to automatically distribute tasks onto a number of worker threads. More...
#include <TaskSystem.h>
Classes | |
struct | TaskData |
Static Public Member Functions | |
Utilities | |
static void | WriteStateSnapshotToDGML (ezDGMLGraph &ref_graph) |
Writes the internal state of the ezTaskSystem as a DGML graph. | |
static void | WriteStateSnapshotToFile (const char *szPath=nullptr) |
Convenience function to write the task graph snapshot to a file. If no path is given, the file is written to ":appdata/TaskGraphs/__date__.dgml". | |
Managing Tasks | |
static ezTaskGroupID | StartSingleTask (const ezSharedPtr< ezTask > &pTask, ezTaskPriority::Enum priority, ezOnTaskGroupFinishedCallback callback=ezOnTaskGroupFinishedCallback()) |
A helper function to insert a single task into the system and start it right away. Returns ID of the Group into which the task has been put. | |
static ezTaskGroupID | StartSingleTask (const ezSharedPtr< ezTask > &pTask, ezTaskPriority::Enum priority, ezTaskGroupID dependency, ezOnTaskGroupFinishedCallback callback=ezOnTaskGroupFinishedCallback()) |
A helper function to insert a single task into the system and start it right away. Returns ID of the Group into which the task has been put. This overload allows to additionally specify a single dependency. | |
static void | FinishFrameTasks () |
Call this function once at the end of a frame. It will ensure that all tasks for 'this frame' get finished properly. More... | |
static ezResult | CancelTask (const ezSharedPtr< ezTask > &pTask, ezOnTaskRunning::Enum onTaskRunning=ezOnTaskRunning::WaitTillFinished) |
This function will try to remove the given task from the work queue, to prevent it from being executed. More... | |
static void | BroadcastClearThreadLocalsEvent () |
Broadcasts ezThreadEvent::ClearThreadLocals on all worker threads. | |
Managing Task Groups | |
static ezTaskGroupID | CreateTaskGroup (ezTaskPriority::Enum priority, ezOnTaskGroupFinishedCallback callback=ezOnTaskGroupFinishedCallback()) |
Creates a new task group for one-time use. Groups need to be recreated every time a task is supposed to be inserted into the system. More... | |
static void | AddTaskToGroup (ezTaskGroupID group, const ezSharedPtr< ezTask > &pTask) |
Adds a task to the given task group. The group must not yet have been started. | |
static void | AddTaskGroupDependency (ezTaskGroupID group, ezTaskGroupID dependsOn) |
Adds a dependency on another group to Group. This means Group will not be execute before DependsOn has finished. More... | |
static void | AddTaskGroupDependencyBatch (ezArrayPtr< const ezTaskGroupDependency > batch) |
Same as AddTaskGroupDependency() but batches multiple dependency additions. | |
static void | StartTaskGroup (ezTaskGroupID group) |
Starts the task group. After this no further modifications on the group (new tasks or dependencies) are allowed. | |
static void | StartTaskGroupBatch (ezArrayPtr< const ezTaskGroupID > batch) |
Same as StartTaskGroup() but batches multiple actions. | |
static bool | IsTaskGroupFinished (ezTaskGroupID group) |
Returns whether the given Group id refers to a task group that has been finished already. More... | |
static ezResult | CancelGroup (ezTaskGroupID group, ezOnTaskRunning::Enum onTaskRunning=ezOnTaskRunning::WaitTillFinished) |
Cancels all the tasks in the given group. More... | |
static void | WaitForGroup (ezTaskGroupID group) |
Blocks until all tasks in the given group have finished. More... | |
static void | WaitForCondition (ezDelegate< bool()> condition) |
Blocks the current thread until the given delegate returns true. More... | |
Thread Management | |
class | ezTaskWorkerThread |
static void | SetWorkerThreadCount (ezInt32 iShortTasks=-1, ezInt32 iLongTasks=-1) |
Sets the number of threads to use for the different task categories. More... | |
static ezUInt32 | GetWorkerThreadCount (ezWorkerThreadType::Enum type) |
Returns the maximum number of threads that should work on the given type of task at the same time. | |
static ezUInt32 | GetNumAllocatedWorkerThreads (ezWorkerThreadType::Enum type) |
Returns the number of threads that have been allocated to potentially work on the given type of task. More... | |
static ezWorkerThreadType::Enum | GetCurrentThreadWorkerType () |
Returns the (thread local) type of tasks that would be executed on this thread. | |
static double | GetThreadUtilization (ezWorkerThreadType::Enum type, ezUInt32 uiThreadIndex, ezUInt32 *pNumTasksExecuted=nullptr) |
Returns the utilization (0.0 to 1.0) of the given thread. Note: This will only be valid, if FinishFrameTasks() is called once per frame. More... | |
static void | WakeUpThreads (ezWorkerThreadType::Enum type, ezUInt32 uiNumThreads) |
[internal] Wakes up or allocates up to uiNumThreads, unless enough threads are currently active and not blocked | |
Parallel For | |
static void | ParallelForIndexed (ezUInt32 uiStartIndex, ezUInt32 uiNumItems, ezParallelForIndexedFunction32 taskCallback, const char *szTaskName=nullptr, ezTaskNesting taskNesting=ezTaskNesting::Never, const ezParallelForParams ¶ms=ezParallelForParams()) |
A helper function to process task items in a parallel fashion by having per-worker index ranges generated. | |
static void | ParallelForIndexed (ezUInt64 uiStartIndex, ezUInt64 uiNumItems, ezParallelForIndexedFunction64 taskCallback, const char *szTaskName=nullptr, ezTaskNesting taskNesting=ezTaskNesting::Never, const ezParallelForParams ¶ms=ezParallelForParams()) |
A helper function to process task items in a parallel fashion by having per-worker index ranges generated. | |
template<typename ElemType , typename Callback > | |
static void | ParallelFor (ezArrayPtr< ElemType > taskItems, Callback taskCallback, const char *szTaskName=nullptr, const ezParallelForParams ¶ms=ezParallelForParams()) |
template<typename ElemType , typename Callback > | |
static void | ParallelForSingle (ezArrayPtr< ElemType > taskItems, Callback taskCallback, const char *szTaskName=nullptr, const ezParallelForParams ¶ms=ezParallelForParams()) |
template<typename ElemType , typename Callback > | |
static void | ParallelForSingleIndex (ezArrayPtr< ElemType > taskItems, Callback taskCallback, const char *szTaskName=nullptr, const ezParallelForParams ¶ms=ezParallelForParams()) |
Misc | |
static void | SetTargetFrameTime (ezTime targetFrameTime=ezTime::MakeFromSeconds(1.0/40.0)) |
Sets the target frame time that is supposed to not be exceeded. More... | |
This system allows to automatically distribute tasks onto a number of worker threads.
By deriving from ezTask you can create your own task types. These can be executed through this task system. You can run a single task using the 'StartSingleTask' function. For more complex setups, it is possible to create groups of tasks, which can have interdependencies. This should be used to group all tasks that belong to one system and need to be done before another system runs. For example you could group all tasks to update particle systems, and then have another group for all tasks to update sound, which depends on the first group, such that sound is only updated after all particle systems are done with.
Although it is possible to wait for tasks or to cancel them, it is generally advised to try to minimize their use. Tasks that might need to be canceled regularly (e.g. path searches) should be implemented in a way that they are aware of being canceled and will stop their work prematurely, instead of running through to the end.
Note that it is crucial to call 'FinishFrameTasks' once per frame, otherwise tasks that need to be executed on the main thread are never executed.
|
static |
Adds a dependency on another group to Group. This means Group will not be execute before DependsOn has finished.
|
static |
Cancels all the tasks in the given group.
EZ_SUCCESS is returned, if all tasks were already finished or could be removed without waiting for any of them. EZ_FAILURE is returned, if at least one task was being processed by another thread and could not be removed without waiting. If bWaitForIt is false, the function cancels all tasks, but returns without blocking, even if not all tasks have been finished. If bWaitForIt is true, the function returns only after it is guaranteed that all tasks are properly terminated.
|
static |
This function will try to remove the given task from the work queue, to prevent it from being executed.
The function will return EZ_SUCCESS, if the task could be removed and thus its execution could be prevented. It will also return EZ_SUCCESS, if the task was already finished and nothing needed to be done. Tasks that are removed without execution will still be marked as 'finished' and dependent tasks will be scheduled.
EZ_FAILURE is returned, if the task had already been started and thus could not be prevented from running.
In case of failure, bWaitForIt determines whether 'WaitForTask' is called (with all its consequences), or whether the function will return immediately.
The cancel flag is set on the task, such that tasks that support canceling might terminate earlier. However, there is no guarantee how long it takes for already running tasks to actually finish. Therefore when bWaitForIt is true, this function might block for a very long time. It is advised to implement tasks that need to be canceled regularly (e.g. path searches for units that might die) in a way that allows for quick canceling.
|
static |
Creates a new task group for one-time use. Groups need to be recreated every time a task is supposed to be inserted into the system.
All tasks that are added to this group will be run with the same given Priority. Once all tasks in the group are finished and thus the group is finished, an optional Callback can be executed.
|
static |
Call this function once at the end of a frame. It will ensure that all tasks for 'this frame' get finished properly.
Calling this function is crucial for several reasons. It is the central function to execute 'main thread' tasks. Otherwise these tasks might never get executed. It also changes the priority of all 'next frame' tasks to 'this frame', so that those tasks are guaranteed to get finished when 'FinishFrameTasks' is called the next time.
Finally this function executes tasks with the priority 'SomeFrameMainThread' as long as the target frame time is not exceeded. You can configure this with SetTargetFrameTime(), which defines how long (in milliseconds) the frame is allowed to be. As long as that time is not exceeded, additional 'SomeFrameMainThread' tasks will be executed. If the frame time spikes for a few frames, no such tasks will be executed, to prevent making it worse. However, if the frame time stays high over a longer period, 'FinishFrameTasks' will execute 'SomeFrameMainThread' tasks every once in a while, to guarantee some progress.
|
static |
Returns the number of threads that have been allocated to potentially work on the given type of task.
CAREFUL! This is not the number of threads that will be active at the same time. Use GetWorkerThreadCount() for that. This is the maximum number of threads that may jump in, if too many threads are blocked. This number will change dynamically at runtime to prevent deadlocks and it can grow very, very large.
|
static |
Returns the utilization (0.0 to 1.0) of the given thread. Note: This will only be valid, if FinishFrameTasks() is called once per frame.
Also optionally returns the number of tasks that were finished during the last frame.
|
static |
Returns whether the given Group id refers to a task group that has been finished already.
There is no time frame in which group IDs are valid. You may call this function at any time, even 10 minutes later, and it will correctly determine the results.
|
static |
A helper function to process task items in a parallel fashion by generating per-worker sub-ranges from an initial item array pointer. Given an array pointer 'taskItems' with elements of type ElemType, the following invocations are possible:
|
static |
A helper function to process task items in a parallel fashion and one-by-one (without global index). Given an array pointer 'taskItems' with elements of type ElemType, the following invocations are possible:
|
static |
A helper function to process task items in a parallel fashion and one-by-one (with global index). Given an array pointer 'taskItems' with elements of type ElemType, the following invocations are possible:
|
static |
Sets the target frame time that is supposed to not be exceeded.
|
static |
Sets the number of threads to use for the different task categories.
uiShortTasks and uiLongTasks must be at least 1 and should not exceed the number of available CPU cores. There will always be exactly one additional thread for file access tasks (ezTaskPriority::FileAccess).
If uiShortTasks or uiLongTasks is smaller than 1, a default number of threads will be used for that type of work. This number of threads depends on the number of available CPU cores. If SetWorkThreadCount is never called, at all, the first time any task is started the number of worker threads is set to this default configuration. Unless you have a good idea how to set up the number of worker threads to make good use of the available cores, it is a good idea to just use the default settings.
|
static |
Blocks the current thread until the given delegate returns true.
If possible, prefer to use WaitForGroup() to wait for some task to finish, as that is the most efficient way. If not possible, prefer to use WaitForCondition() instead of rolling your own busy-loop for polling some state. WaitForCondition() will NOT put the current thread to sleep, but instead keep polling the delegate. However, in between, it will try to execute other tasks and if there are no tasks that it could take on, it will wake up another worker thread thus guaranteeing, that there are enough unblocked threads in the system to do all the work.
|
static |
Blocks until all tasks in the given group have finished.
If you need to wait for some other task to finish, this should always be the preferred method to do so. WaitForGroup will put the current thread to sleep and use thread signals to only wake it up again once the group is indeed finished. This is the most efficient way to wait for a task.