cmake 引入 oneTBB
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
set(Renderive_Kernel_dependencies global::taskflow)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/cmake/rely.cmake)
|
||||
set(Renderive_Kernel_dependencies global::taskflow render_kernel::oneTBB)
|
||||
if (RENDERIVE_BUILD_TESTS)
|
||||
set(Renderive_Kernel_test_targets)
|
||||
list(APPEND Renderive_Kernel_dependencies global::GTest)
|
||||
@@ -13,6 +14,7 @@ endif ()
|
||||
rcl_load_dependency_environment(${Renderive_Kernel_dependencies})
|
||||
find_package(Taskflow CONFIG REQUIRED)
|
||||
find_package(Threads REQUIRED)
|
||||
find_package(TBB CONFIG REQUIRED)
|
||||
if (RENDERIVE_BUILD_TESTS)
|
||||
find_package(GTest CONFIG REQUIRED)
|
||||
endif ()
|
||||
@@ -23,7 +25,9 @@ target_include_directories(Renderive_Kernel PUBLIC
|
||||
"$<BUILD_INTERFACE:${Renderive_Kernel_source_dir}>"
|
||||
)
|
||||
target_compile_features(Renderive_Kernel PUBLIC cxx_std_20)
|
||||
target_link_libraries(Renderive_Kernel PRIVATE Taskflow::Taskflow Threads::Threads)
|
||||
target_link_libraries(Renderive_Kernel PRIVATE Taskflow::Taskflow)
|
||||
target_link_libraries(Renderive_Kernel PRIVATE TBB::tbb)
|
||||
target_link_libraries(Renderive_Kernel PRIVATE Threads::Threads)
|
||||
if (MSVC)
|
||||
target_compile_options(Renderive_Kernel PRIVATE /utf-8)
|
||||
endif ()
|
||||
@@ -53,7 +57,7 @@ if (RENDERIVE_BUILD_TESTS)
|
||||
endforeach ()
|
||||
add_custom_target(Renderive_Kernel_check
|
||||
COMMAND "${CMAKE_CTEST_COMMAND}" --test-dir "${CMAKE_BINARY_DIR}"
|
||||
-C "$<CONFIG>" -L "^Renderive_Kernel$" --output-on-failure
|
||||
-C "$<CONFIG>" -L "^Renderive_Kernel$" --output-on-failure
|
||||
DEPENDS ${Renderive_Kernel_test_targets}
|
||||
USES_TERMINAL)
|
||||
endif ()
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
include_guard(GLOBAL)
|
||||
block()
|
||||
rcl_init(render_kernel)
|
||||
_register_git_cmake_library(render_kernel::oneTBB
|
||||
"https://github.com/uxlfoundation/oneTBB.git"
|
||||
"v2023.1.0"
|
||||
)
|
||||
rcl_get_effective_install_dir(render_kernel::oneTBB ONETBB_ROOT)
|
||||
set(TBB_CONFIG_DIR "${ONETBB_ROOT}/lib/cmake/TBB")
|
||||
rcl_cmake_library_set_cmake_options(render_kernel::oneTBB ${oneTBB_option})
|
||||
rcl_cmake_library_set_other_use_opt(render_kernel::oneTBB
|
||||
"-DTBB_DIR=\"${TBB_CONFIG_DIR}\""
|
||||
)
|
||||
rcl_cmake_library_set_init_script(render_kernel::oneTBB
|
||||
"set(ONETBB_ROOT \"${ONETBB_ROOT}\")"
|
||||
"set(TBB_DIR \"${TBB_CONFIG_DIR}\")"
|
||||
)
|
||||
rcl_cmake_library_set_clear_script(render_kernel::oneTBB
|
||||
"unset(ONETBB_ROOT)"
|
||||
"unset(TBB_DIR)"
|
||||
)
|
||||
endblock()
|
||||
-770
@@ -1,770 +0,0 @@
|
||||
# Renderive 当前架构核实与改造 TODO
|
||||
|
||||
## P0:External Operation 生命周期与失败语义
|
||||
|
||||
### TODO-01:核实 External Operation 是否存在永久 pending 风险
|
||||
|
||||
* [ ] 阅读 `Kernel/src/renderive/render_graph/External_Operation.hpp`
|
||||
* [ ] 明确 `External_Operation_Source` 当前生命周期规则
|
||||
* [ ] 核实 Source 被析构但未调用 `complete()` / `fail()` 时,Operation 的最终状态
|
||||
* [ ] 编写测试:创建 Operation 后直接销毁 Source
|
||||
* [ ] 验证 `Render_Graph_Runtime` 是否会永久停留在 `waiting_external`
|
||||
* [ ] 验证 graph future / frame completion 是否会永久阻塞
|
||||
* [ ] 检查 Datoviz GPU completion 所有异常路径是否保证最终 complete/fail
|
||||
|
||||
**核实目标:**
|
||||
|
||||
确认是否存在:
|
||||
|
||||
```text
|
||||
producer 消失
|
||||
↓
|
||||
External_Operation 永久 pending
|
||||
↓
|
||||
node 永久 waiting_external
|
||||
↓
|
||||
frame 永久无法完成
|
||||
```
|
||||
|
||||
**如果问题成立,再考虑改造:**
|
||||
|
||||
* [ ] 为 External Operation 定义明确 terminal states
|
||||
|
||||
```text
|
||||
pending
|
||||
completed
|
||||
failed
|
||||
cancelled / abandoned / broken
|
||||
```
|
||||
|
||||
* [ ] Source 析构时处理未完成 Operation
|
||||
* [ ] 明确 broken producer 应映射为:
|
||||
|
||||
* failure
|
||||
* cancellation
|
||||
* abandoned
|
||||
* [ ] 保证 completion callback 只执行一次
|
||||
* [ ] 保证 complete/fail/cancel 与析构竞态安全
|
||||
* [ ] 增加 double-complete / complete-after-fail 等测试
|
||||
* [ ] 增加 Runtime 等待 external 时 producer 异常退出测试
|
||||
|
||||
---
|
||||
|
||||
### TODO-02:核实 Render Graph failure 后是否可能等待无关 External Operation
|
||||
|
||||
重点位置:
|
||||
|
||||
```text
|
||||
Render_Graph_Runtime.cpp
|
||||
```
|
||||
|
||||
特别检查 graph 结束条件中:
|
||||
|
||||
```text
|
||||
failed
|
||||
active_tasks
|
||||
waiting_external
|
||||
unfinished_nodes
|
||||
```
|
||||
|
||||
之间的关系。
|
||||
|
||||
* [ ] 构造两个并行 async node:A、B
|
||||
* [ ] A 主动 fail
|
||||
* [ ] B 永久不回调
|
||||
* [ ] 验证整个 graph 是否永久不返回
|
||||
* [ ] 构造 A fail、B 正常延迟完成
|
||||
* [ ] 验证失败 frame 的 completion 时间是否被 B 强制拖长
|
||||
* [ ] 明确当前设计到底是:
|
||||
|
||||
* fail-fast
|
||||
* drain-before-fail
|
||||
* cooperative cancellation
|
||||
|
||||
**如果问题成立,再决定语义。**
|
||||
|
||||
推荐先明确 contract,不要直接写代码:
|
||||
|
||||
```text
|
||||
方案 A:fail-fast
|
||||
一个节点失败后,frame 尽快失败返回。
|
||||
|
||||
方案 B:drain
|
||||
一个节点失败后,已启动外部操作仍全部收尾后再返回。
|
||||
|
||||
方案 C:cancel + drain
|
||||
请求其他 operation cancellation,
|
||||
无法取消的 operation 做后台资源回收,
|
||||
但 frame logical completion 可以提前结束。
|
||||
```
|
||||
|
||||
* [ ] 根据 Renderive 的资源安全要求确定一种正式语义
|
||||
* [ ] 再增加对应 Runtime 状态机和测试
|
||||
|
||||
---
|
||||
|
||||
## P1:Render Plan 生命周期与重复编译
|
||||
|
||||
### TODO-03:核实 Render_Plan_History 是否长期无限增长
|
||||
|
||||
重点检查:
|
||||
|
||||
```text
|
||||
Render_Plan.cpp
|
||||
Render_Plan_History
|
||||
compile_render_plan()
|
||||
```
|
||||
|
||||
当前重点假设:
|
||||
|
||||
```text
|
||||
只与 plans_.back() 比较 topology
|
||||
```
|
||||
|
||||
可能出现:
|
||||
|
||||
```text
|
||||
Topology A
|
||||
Topology B
|
||||
Topology A
|
||||
Topology B
|
||||
...
|
||||
```
|
||||
|
||||
导致历史:
|
||||
|
||||
```text
|
||||
A1 B2 A3 B4 A5 B6 ...
|
||||
```
|
||||
|
||||
* [ ] 确认 `Render_Plan_History` 是否只 dedupe 相邻 topology
|
||||
* [ ] 确认旧 Render Plan 是否存在必须永久保存的语义
|
||||
* [ ] 检查 Capture 是否持有具体 Plan
|
||||
* [ ] 检查 Observation / Analysis 是否依赖历史 Plan 对象
|
||||
* [ ] 模拟 10 万帧 A/B topology 交替
|
||||
* [ ] 观察:
|
||||
|
||||
* plan 数量
|
||||
* 内存占用
|
||||
* version 增长
|
||||
* [ ] 确认长期运行是否确实存在无界增长
|
||||
|
||||
**如果成立,再选择方案:**
|
||||
|
||||
### 方案 A:Topology Interning
|
||||
|
||||
* [ ] 为 topology 计算稳定 fingerprint/hash
|
||||
* [ ] 相同 topology 复用已有 immutable Render Plan
|
||||
|
||||
```text
|
||||
topology fingerprint
|
||||
↓
|
||||
Render_Plan cache
|
||||
```
|
||||
|
||||
### 方案 B:Bounded History
|
||||
|
||||
* [ ] History 保留最近 N 个 plan
|
||||
* [ ] Capture 对需要长期保存的 Plan 单独持有 shared_ptr
|
||||
|
||||
### 方案 C:二者结合
|
||||
|
||||
* [ ] topology cache
|
||||
* [ ] bounded observation history
|
||||
* [ ] capture 独立 pin
|
||||
|
||||
优先研究方案 C。
|
||||
|
||||
---
|
||||
|
||||
### TODO-04:核实 Render Plan 是否每帧重复编译执行拓扑
|
||||
|
||||
重点检查:
|
||||
|
||||
```text
|
||||
Scene_Base::compile_render_plan()
|
||||
Render_Graph_Runtime constructor
|
||||
```
|
||||
|
||||
核实每帧是否重复执行:
|
||||
|
||||
```text
|
||||
node id → index map
|
||||
successor adjacency
|
||||
indegree
|
||||
topological sort
|
||||
cycle validation
|
||||
```
|
||||
|
||||
* [ ] 使用 profiler 测量 Runtime constructor 成本
|
||||
* [ ] 分别测试:
|
||||
|
||||
* 10 nodes
|
||||
* 50 nodes
|
||||
* 100 nodes
|
||||
* 500 nodes
|
||||
* 1000 nodes
|
||||
* [ ] 测量每帧:
|
||||
|
||||
* Render Plan compile 时间
|
||||
* Runtime construction 时间
|
||||
* topology validation 时间
|
||||
* [ ] 与真实 node execution 时间比较
|
||||
* [ ] 判断这部分是否已经进入 critical path
|
||||
|
||||
**只有测量证明值得优化时再改。**
|
||||
|
||||
潜在目标结构:
|
||||
|
||||
```text
|
||||
Render_Plan
|
||||
├─ Logical metadata
|
||||
└─ Compiled Execution Layout
|
||||
├─ node execution index
|
||||
├─ predecessor count[]
|
||||
├─ successor offset[]
|
||||
├─ successors[]
|
||||
└─ static topology metadata
|
||||
```
|
||||
|
||||
每帧 Runtime 只生成:
|
||||
|
||||
```text
|
||||
remaining_predecessors[]
|
||||
node_status[]
|
||||
timestamps[]
|
||||
external state
|
||||
```
|
||||
|
||||
* [ ] 尽量避免每帧重新构造 immutable topology
|
||||
* [ ] 保持 Render Plan 本身 immutable
|
||||
* [ ] 不把 per-frame execution state 塞回 Render Plan
|
||||
* [ ] benchmark 改造前后成本
|
||||
|
||||
---
|
||||
|
||||
## P1:调度模型规模化核实
|
||||
|
||||
### TODO-05:统计每个 Scene 实际线程成本
|
||||
|
||||
当前重点检查:
|
||||
|
||||
```text
|
||||
Scene_Base worker thread
|
||||
|
||||
3D Point Scene:
|
||||
Render_Domain thread
|
||||
Gpu_Completion_Service thread
|
||||
|
||||
Global:
|
||||
Taskflow Executor workers
|
||||
```
|
||||
|
||||
* [ ] 启动 1 个 3D Scene,记录线程数
|
||||
* [ ] 启动 10 个 Scene
|
||||
* [ ] 启动 50 个 Scene
|
||||
* [ ] 启动 100 个 Scene
|
||||
* [ ] 测量:
|
||||
|
||||
* OS thread 数量
|
||||
* context switches
|
||||
* idle CPU
|
||||
* memory/thread stack
|
||||
* frame latency
|
||||
* scheduler wait
|
||||
* [ ] 明确 Renderive 目标部署规模:
|
||||
|
||||
* 单桌面程序 1~4 Scene
|
||||
* 多窗口
|
||||
* Web 多 session
|
||||
* server-side rendering
|
||||
|
||||
**如果目标只是少量本地 Scene:**
|
||||
|
||||
* [ ] 暂不修改
|
||||
|
||||
**如果未来需要大量 Scene:**
|
||||
|
||||
* [ ] 研究共享 Render Domain
|
||||
* [ ] 研究共享 GPU Completion Service
|
||||
* [ ] Render Domain 按 device/backend 而不是按 Scene 划分
|
||||
* [ ] 使用 serial executor / strand 保持 backend affinity
|
||||
|
||||
目标可能演化为:
|
||||
|
||||
```text
|
||||
Global CPU Executor
|
||||
|
||||
GPU Device 0
|
||||
├─ Shared Render Domain
|
||||
│ ├─ Scene A
|
||||
│ ├─ Scene B
|
||||
│ └─ Scene C
|
||||
│
|
||||
└─ Shared Completion Service
|
||||
├─ fence A
|
||||
├─ fence B
|
||||
└─ fence C
|
||||
```
|
||||
|
||||
**不要在没有多 Scene 压测数据之前重构这一项。**
|
||||
|
||||
---
|
||||
|
||||
## P2:Frame Pipeline 能力边界确认
|
||||
|
||||
### TODO-06:确认当前 Scene 是否严格 single-frame-in-flight
|
||||
|
||||
重点检查:
|
||||
|
||||
```text
|
||||
Scene_Base::submit_render()
|
||||
Scene_Base::lock_render_idle()
|
||||
```
|
||||
|
||||
* [ ] 验证 GPU external operation 未完成时,下一帧 CPU DAG 能否开始
|
||||
* [ ] 确认当前行为是否:
|
||||
|
||||
```text
|
||||
Frame N CPU
|
||||
↓
|
||||
Frame N GPU
|
||||
↓
|
||||
Frame N complete
|
||||
↓
|
||||
Frame N+1 CPU
|
||||
```
|
||||
|
||||
而不是:
|
||||
|
||||
```text
|
||||
Frame N GPU
|
||||
+
|
||||
Frame N+1 CPU
|
||||
```
|
||||
|
||||
* [ ] 测量这种设计对 interactive latency 的影响
|
||||
* [ ] 验证 low-latency 模式下 GPU queue 是否保持浅队列
|
||||
* [ ] 验证 frame age 是否优于多帧堆积方案
|
||||
|
||||
**当前阶段不要默认这是问题。**
|
||||
|
||||
明确记录设计决策:
|
||||
|
||||
```text
|
||||
Interactive mode:
|
||||
优先 latency
|
||||
→ single-frame-in-flight 可以是正确策略
|
||||
|
||||
Throughput / offline mode:
|
||||
优先 throughput
|
||||
→ 未来可能需要 multi-frame-in-flight
|
||||
```
|
||||
|
||||
* [ ] 只有出现离线渲染/视频/批处理需求时再设计跨帧流水线
|
||||
|
||||
---
|
||||
|
||||
## P2:Scene_Base 职责边界检查
|
||||
|
||||
### TODO-07:持续监控 Scene_Base 是否演化成 God Object
|
||||
|
||||
盘点当前职责:
|
||||
|
||||
```text
|
||||
Renderable lifetime
|
||||
Scene state
|
||||
Snapshot
|
||||
Dependency
|
||||
Render plan compile
|
||||
Frame submission
|
||||
Worker control
|
||||
Edit queue
|
||||
Exception propagation
|
||||
Observation
|
||||
Capture integration
|
||||
Frame control
|
||||
Memory domain
|
||||
```
|
||||
|
||||
* [ ] 给 Scene_Base 当前职责做一次正式列表
|
||||
* [ ] 检查每个职责是否属于 orchestration
|
||||
* [ ] 新功能进入 Scene_Base 前必须判断能否成为独立 subsystem
|
||||
|
||||
特别避免未来加入:
|
||||
|
||||
```text
|
||||
GPU fence logic
|
||||
backend-specific synchronization
|
||||
generic async continuation internals
|
||||
capture storage internals
|
||||
scheduler implementation internals
|
||||
GPU profiler implementation
|
||||
```
|
||||
|
||||
应继续保持:
|
||||
|
||||
```text
|
||||
Scene_Base
|
||||
↓ orchestrate
|
||||
|
||||
Render_Graph_Runtime
|
||||
External_Operation
|
||||
Render_Domain
|
||||
Gpu_Completion_Service
|
||||
Capture subsystem
|
||||
Observation subsystem
|
||||
```
|
||||
|
||||
**当前不建议仅为了减小文件而拆类。**
|
||||
|
||||
只有当职责本身形成独立生命周期/状态机时再拆。
|
||||
|
||||
---
|
||||
|
||||
## P2:Taskflow 依赖边界确认
|
||||
|
||||
### TODO-08:正式确认 Taskflow 只是 Executor,而不是架构语义的一部分
|
||||
|
||||
当前目标模型:
|
||||
|
||||
```text
|
||||
Render_Graph_Runtime
|
||||
↓
|
||||
CPU Scheduler Adapter
|
||||
↓
|
||||
tf::Executor::silent_async()
|
||||
```
|
||||
|
||||
* [ ] 搜索所有 `tf::` 使用点
|
||||
* [ ] 检查 Renderable / Render Plan / External Operation 是否泄漏 Taskflow 类型
|
||||
* [ ] 检查 Render_Graph_Runtime 是否依赖 Taskflow DAG API
|
||||
* [ ] 确认 Taskflow 只承担 CPU function dispatch
|
||||
* [ ] 做一个最小 mock executor 测试
|
||||
|
||||
例如:
|
||||
|
||||
```cpp
|
||||
scheduler([] {
|
||||
...
|
||||
});
|
||||
```
|
||||
|
||||
替换成测试 executor 后 Runtime 仍正常运行。
|
||||
|
||||
* [ ] 如果成立,记录架构结论:
|
||||
|
||||
```text
|
||||
Taskflow is an implementation detail of CPU execution,
|
||||
not Renderive's task graph model.
|
||||
```
|
||||
|
||||
**如果已经成立,不需要再额外设计 Scheduler Concept。**
|
||||
|
||||
先保持最小 callable abstraction 即可。
|
||||
|
||||
---
|
||||
|
||||
## P2:Datoviz Async 接入完整性核实
|
||||
|
||||
### TODO-09:逐条核实 GPU completion 所有路径都完成 External Operation
|
||||
|
||||
检查:
|
||||
|
||||
```text
|
||||
Point_Scene
|
||||
Render_Domain
|
||||
Gpu_Completion_Service
|
||||
Datoviz backend
|
||||
```
|
||||
|
||||
覆盖以下路径:
|
||||
|
||||
* [ ] 正常 submit
|
||||
* [ ] submit 失败
|
||||
* [ ] fence 创建失败
|
||||
* [ ] fence wait 失败
|
||||
* [ ] device lost
|
||||
* [ ] Render_Domain callback 抛异常
|
||||
* [ ] backend.collect() 抛异常
|
||||
* [ ] Scene 被销毁
|
||||
* [ ] application shutdown
|
||||
* [ ] completion service shutdown
|
||||
* [ ] frame 被逻辑取消
|
||||
* [ ] GPU operation 已提交但 Scene 生命周期结束
|
||||
|
||||
每条路径都验证最终发生:
|
||||
|
||||
```text
|
||||
complete
|
||||
或
|
||||
fail/cancel
|
||||
```
|
||||
|
||||
不能:
|
||||
|
||||
```text
|
||||
silent disappearance
|
||||
→ External Operation 永久 pending
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## P2:CPU / GPU 观测数据可信度核实
|
||||
|
||||
### TODO-10:验证节点时间戳语义
|
||||
|
||||
针对:
|
||||
|
||||
```text
|
||||
ready_time
|
||||
start_time
|
||||
cpu_end_time
|
||||
external_start_time
|
||||
external_end_time
|
||||
end_time
|
||||
```
|
||||
|
||||
逐项明确语义。
|
||||
|
||||
* [ ] `ready_time` 是否表示所有 dependency 已满足
|
||||
* [ ] `start_time - ready_time` 是否能准确代表 scheduler wait
|
||||
* [ ] `cpu_end_time - start_time` 是否代表 CPU node execution
|
||||
* [ ] external_start 是否发生在 CPU submit 完成附近
|
||||
* [ ] external_end 是否由真正的 external completion 驱动
|
||||
* [ ] node end 是否与 dependency unlock 同一语义点
|
||||
* [ ] worker_id 是否只表示 CPU execution worker
|
||||
* [ ] external completion thread 是否不会错误覆盖 worker_id
|
||||
|
||||
---
|
||||
|
||||
### TODO-11:验证 Critical Path 算法
|
||||
|
||||
* [ ] 手工构造简单 DAG
|
||||
|
||||
```text
|
||||
A 10ms ── C 5ms
|
||||
B 20ms ──┘
|
||||
```
|
||||
|
||||
期望 critical path:
|
||||
|
||||
```text
|
||||
B → C = 25ms
|
||||
```
|
||||
|
||||
* [ ] 增加 external node
|
||||
* [ ] 增加 scheduler wait
|
||||
* [ ] 明确 critical path 是否统计:
|
||||
|
||||
* CPU execution
|
||||
* external wait
|
||||
* scheduler wait
|
||||
* dependency wait
|
||||
* [ ] 明确算法计算的是:
|
||||
|
||||
* DAG theoretical execution critical path
|
||||
* 还是 observed wall-clock critical path
|
||||
|
||||
两者不能混淆。
|
||||
|
||||
---
|
||||
|
||||
### TODO-12:验证 GPU timing 与 fence wait 的区别
|
||||
|
||||
确保以下数据不会混用:
|
||||
|
||||
```text
|
||||
GPU timestamp duration
|
||||
≠
|
||||
CPU fence waiting duration
|
||||
```
|
||||
|
||||
* [ ] GPU render timestamp
|
||||
* [ ] transition timestamp
|
||||
* [ ] copy timestamp
|
||||
* [ ] total GPU timestamp
|
||||
* [ ] CPU submit duration
|
||||
* [ ] completion service fence wait duration
|
||||
* [ ] readback duration
|
||||
|
||||
输出报告时必须保持这些概念分离。
|
||||
|
||||
---
|
||||
|
||||
## P3:Low Latency / Frame Control 回归测试
|
||||
|
||||
### TODO-13:正式锁定 latest-frame-wins 的行为语义
|
||||
|
||||
* [ ] 测试 pending frame 被替换
|
||||
* [ ] 测试 rendering frame 不会被中断
|
||||
* [ ] 测试事件修改模型后,新 snapshot 能看到状态
|
||||
* [ ] 测试被替换 frame 不会导致权威模型状态丢失
|
||||
* [ ] 测试 burst input:
|
||||
|
||||
* mouse move
|
||||
* resize
|
||||
* camera control
|
||||
* rapid data update
|
||||
* [ ] 记录:
|
||||
|
||||
* produced frames
|
||||
* rendered frames
|
||||
* dropped/replaced frames
|
||||
* input-to-present latency
|
||||
|
||||
明确:
|
||||
|
||||
```text
|
||||
丢的是待展示/待处理 frame
|
||||
不是 authoritative scene state
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## P3:Runtime 压测
|
||||
|
||||
### TODO-14:建立标准 DAG benchmark
|
||||
|
||||
固定测试:
|
||||
|
||||
```text
|
||||
10 nodes
|
||||
50 nodes
|
||||
100 nodes
|
||||
500 nodes
|
||||
1000 nodes
|
||||
```
|
||||
|
||||
分别包含:
|
||||
|
||||
```text
|
||||
完全串行
|
||||
完全并行
|
||||
树形
|
||||
diamond
|
||||
随机 DAG
|
||||
CPU + External 混合 DAG
|
||||
```
|
||||
|
||||
记录:
|
||||
|
||||
* [ ] graph compile time
|
||||
* [ ] runtime setup time
|
||||
* [ ] scheduler wait
|
||||
* [ ] total CPU work
|
||||
* [ ] wall time
|
||||
* [ ] parallelism
|
||||
* [ ] Taskflow worker utilization
|
||||
* [ ] Runtime lock contention
|
||||
* [ ] completion callback cost
|
||||
|
||||
后续任何 scheduler 改造都与此 benchmark 对比。
|
||||
|
||||
---
|
||||
|
||||
### TODO-15:建立 Renderive 实际 workload benchmark
|
||||
|
||||
不要只做 synthetic benchmark。
|
||||
|
||||
至少保留:
|
||||
|
||||
* [ ] 纯 2D 场景
|
||||
* [ ] 小型 3D point scene
|
||||
* [ ] 大型 3D point scene
|
||||
* [ ] 多 Renderable dependency
|
||||
* [ ] frequent update
|
||||
* [ ] low-latency input
|
||||
* [ ] GPU-heavy
|
||||
* [ ] CPU-heavy
|
||||
* [ ] mixed CPU/GPU
|
||||
|
||||
每次架构改造比较:
|
||||
|
||||
```text
|
||||
P50
|
||||
P95
|
||||
P99
|
||||
|
||||
critical path
|
||||
scheduler wait
|
||||
CPU work
|
||||
GPU duration
|
||||
frame age
|
||||
memory
|
||||
thread count
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 暂时不要做的事情
|
||||
|
||||
下面这些目前没有证据证明值得做:
|
||||
|
||||
* [ ] **不要**再包一层复杂 Taskflow abstraction
|
||||
* [ ] **不要**给 `Scene_Render_Context` 增加 continuation
|
||||
* [ ] **不要**为了异步统一而全面 coroutine 化
|
||||
* [ ] **不要**现在实现 multi-frame-in-flight
|
||||
* [ ] **不要**仅为了减少线程数重写整个 Scene scheduler
|
||||
* [ ] **不要**仅为了“架构漂亮”拆 Scene_Base
|
||||
* [ ] **不要**重复实现 Taskflow 自己已经能完成的线程池能力
|
||||
* [ ] **不要**在没有 profiler 数据时优化 DAG 微小调度开销
|
||||
|
||||
---
|
||||
|
||||
# 建议执行顺序
|
||||
|
||||
```text
|
||||
第一阶段:正确性
|
||||
TODO-01 External Operation 生命周期
|
||||
TODO-02 failure / cancellation
|
||||
TODO-09 Datoviz 异常路径
|
||||
|
||||
第二阶段:长期运行稳定性
|
||||
TODO-03 Render Plan History
|
||||
TODO-10/11/12 观测数据可信度
|
||||
|
||||
第三阶段:CPU Runtime 成本
|
||||
TODO-04 Render Plan compiled layout
|
||||
TODO-14 synthetic benchmark
|
||||
TODO-15 real workload benchmark
|
||||
|
||||
第四阶段:规模化
|
||||
TODO-05 多 Scene thread model
|
||||
TODO-06 multi-frame-in-flight 是否真的需要
|
||||
|
||||
持续性约束
|
||||
TODO-07 Scene_Base 边界
|
||||
TODO-08 Taskflow implementation-detail 边界
|
||||
TODO-13 Low Latency 回归测试
|
||||
```
|
||||
|
||||
## 最终原则
|
||||
|
||||
每一项都严格走:
|
||||
|
||||
```text
|
||||
提出怀疑
|
||||
↓
|
||||
写最小复现 / benchmark
|
||||
↓
|
||||
确认问题是否真实存在
|
||||
↓
|
||||
量化严重程度
|
||||
↓
|
||||
定义行为 contract
|
||||
↓
|
||||
再修改实现
|
||||
↓
|
||||
回归测试 + benchmark
|
||||
```
|
||||
|
||||
不要变成:
|
||||
|
||||
```text
|
||||
看到一个理论缺陷
|
||||
↓
|
||||
立刻重新设计架构
|
||||
```
|
||||
|
||||
现阶段 Renderive 更需要的是**验证和收敛**,而不是继续扩张调度抽象。
|
||||
Reference in New Issue
Block a user