简介: TaskGraph 是 UE 引擎并行计算骨架,驱动渲染/物理/动画等高性能模块的任务调度框架
TaskGraph
入口文件 Engine/Source/Runtime/Core/Public/Async/TaskGraphInterfaces.h
| 类别 | 知识点 | 说明 | 关键接口/类 |
|---|---|---|---|
| 核心组件 | FTaskGraphInterface |
全局任务系统的入口,提供任务调度、线程管理等接口。通过 FTaskGraphInterface::Get() 获取单例实例。 |
FTaskGraphInterface, FTaskGraphImplementation
|
FWorkerThread |
工作线程实体,包含任务队列(FTaskQueue)和线程状态机(运行、休眠等)。 |
FWorkerThread, FThreadTaskQueue
|
|
TFunctionGraphTaskImpl |
Lambda 类型的 任务 | TFunctionGraphTaskImpl::DoTask |
|
FSimpleDelegateGraphTask |
简单的委托类型任务 | FSimpleDelegateGraphTask::DoTask |
|
FDelegateGraphTask |
支持更多特性的委托类型任务 | FDelegateGraphTask::DoTask |
|
FTriggerEventGraphTask |
时间驱动类型的任务 | FTriggerEventGraphTask::DoTask |
|
FNullGraphTask |
空任务类型,用于聚合其它任务 | FNullGraphTask::DoTask |
|
FReturnGraphTask |
特殊任务,将指定名线程的控制流返回给原始调用者 | FReturnGraphTask::DoTask |
|
TGraphTask |
核心任务单元,封装任务逻辑(FBaseGraphTask::Execute)TGraphTask::ExecuteTask,支持依赖关系(FGraphEventRef)。 |
TGraphTask<T>, FGraphEventRef
|
|
| 任务调度 | 任务提交(Dispatch) | 通过 TGraphTask::CreateTask() 创建任务,ConstructAndDispatchWhenReady() 提交到任务队列。 |
TGraphTask::CreateTask(), ConstructAndDispatchWhenReady()
|
DispatchSubsequents |
任务完成后触发依赖此任务的后续任务 | FBaseGraphTask::DispatchSubsequents |
|
| 线程分配(Named Threads) | 任务可指定在特定命名线程(如 GameThread, RHIThread)或任意工作线程(AnyThread)执行。 |
ENamedThreads, FBaseGraphTask::Execute()
|
|
| 优先级系统 | 支持 5 级优先级(High/Normal/Low 等),通过 ENamedThreads 的位掩码指定。 |
ENamedThreads::Type |
|
| 依赖控制 | FGraphEventRef |
任务完成事件,用于实现依赖链。任务完成时触发事件,唤醒等待的任务。 | FGraphEventRef = TRefCountPtr<FBaseGraphTask>; |
| 等待任务完成 |
FTaskGraphInterface::WaitUntilTaskCompletes() 阻塞当前线程直至任务完成。 |
FTaskGraphInterface::WaitUntilTaskCompletes() |
|
| 系统初始化 | 线程池初始化 | 在引擎启动时(FEngineLoop::PreInitPreStartupScreen())初始化 TaskGraph 线程池,默认线程数 = CPU 核心数 - 1。 |
FTaskGraphInterface::Startup(FPlatformMisc::NumberOfWorkerThreadsToSpawn()); |
| 调试与分析 | 任务跟踪工具 | 使用 TASKGRAPH_SCOPE_CYCLE_COUNTER 统计任务耗时,或用 Unreal Insights 可视化任务调度。 |
TASKGRAPH_SCOPE_CYCLE_COUNTER, UE_TRACE_TASK_* 宏 |
| 扩展机制 | 自定义任务类型 | 继承 FNonAbandonableTask 或实现 DoTask(),需确保线程安全(无共享状态)。 |
CanAbandon(), Abandon()
|
| 任务代理(Task Proxies) | 专有线程(如 RHIThread)通过 FTaskThread 代理执行任务,避免阻塞主线程。 |
FTaskThread, FRunnableThread
|
阅读记录
- explicit 禁用类型隐式转换
// 没有 explicit 时可能的错误用法:
void Process(FGraphEventArray* prereqs) {
TGraphTask task = prereqs; // 隐式转换:危险!
}
// 有 explicit 时:
void Process(FGraphEventArray* prereqs) {
// TGraphTask task = prereqs; // 错误:禁止隐式转换
TGraphTask task(prereqs); // 正确:必须显式构造
}
- ETaskState 对应的各阶段
/*
* (I)nitThread: STORE(I)----------------------CAS(C)----------------------
* (C)ancelingThread: --->| Ready |<-->| CanceledAndReady |
* ---------------------- ----------------------
* |OR(L) |OR(L)
* V V
* (L)aunchingThread: --------------------------------------------------CAS(E)----------------------CAS(C)----------------------
* (C)ancelingThread: | Running |<---| Scheduled |<-->| Canceled |
* (E)xpeditingThread: -------------------------------------------------- ---------------------- ----------------------
* |OR(E) |OR(W) |OR(W) |OR(W)
* V V V V
* (W)orkerThread: ---------------------- OR(E)---------------------- ---------------------- ----------------------
* (E)xpeditingThread: | Expedited |<---| Expediting | | Running | | CanceledAndRunning |
* ---------------------- ---------------------- ---------------------- ----------------------
* |OR(W,E) |OR(W) |OR(W)
* V V V
* (W)orkerThread: ---------------------- ---------------------- ----------------------
* (E)xpeditingThread: |ExpeditedAndCompleted | | Completed | | CanceledAndCompleted |
* ---------------------- ---------------------- ----------------------
*/
enum class ETaskState : int8
{
ReadyState = 0,
CanceledFlag = 1 << 0,
ScheduledFlag = 1 << 1,
RunningFlag = 1 << 2,
ExpeditingFlag = 1 << 3,
ExpeditedFlag = 1 << 4,
CompletedFlag = 1 << 5, //the default state when we create a handle
Count = (1 << 6) - 1,
Ready = ReadyState, //means the Task is ready to be launched
CanceledAndReady = Ready | CanceledFlag, //means the task was canceled and is ready to be launched (it still is required to be launched)
Scheduled = Ready | ScheduledFlag, //means the task is launched and therefore queued for execution by a worker
Canceled = CanceledAndReady | ScheduledFlag, //means the task was canceled and launched and therefore queued for execution by a worker (which already might be executing it's continuation)
Running = Scheduled | RunningFlag, //means the task is executing it's runnable and continuation by a worker
CanceledAndRunning = Canceled | RunningFlag, //means the task is executing it's continuation but the runnable was cancelled
Expediting = Running | ExpeditingFlag, //means the task is expediting and the scheduler has released it's reference to the expediting thread before that was finished
Expedited = Expediting | ExpeditedFlag, //means the task was expedited
Completed = Running | CompletedFlag, //means the task is completed with execution
ExpeditedAndCompleted = Expedited | CompletedFlag, //means the task is completed with execution and the runnable was expedited
CanceledAndCompleted = CanceledAndRunning | CompletedFlag, //means the task is completed with execution of it's continuation but the runnable was cancelled
};
ENUM_CLASS_FLAGS(ETaskState)