UE5 系统浏览之 TaskGraph(多线程任务系统)

简介: 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::ExecuteTGraphTask::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)
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容