Files
Convention-Unity-Demo/.tasks/2025-12-01_1_performance_optimization_aggressive.md

417 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 背景
文件名2025-12-01_1_performance_optimization_aggressive.md
创建于2025-12-01
创建者User
主分支main
任务分支task/performance_optimization_aggressive_2025-12-01_1
Yolo模式Off
# 任务描述
对Unity音游编辑器项目进行激进的、彻底的性能优化使用最先进的技术栈。项目限定在Windows 10+平台运行。
## 核心问题
基于Tracy Profiler分析结果
1. **SplineNode.ScriptUpdate**: 5.66ms (19.37%), 3,240次调用 - 函数调用开销过大
2. **递归Update模式**: 深度树形遍历导致缓存不友好
3. **剪枝不彻底**: 大量对象在非活跃时间范围内仍在Update
4. **Timeline UI更新**: 存在严重性能开销(已知问题)
## 性能目标
- 将SplineNode.ScriptUpdate从5.66ms优化到<0.5ms**10倍以上提升**
- 帧率从77fps提升到120fps+
- 消除不必要的Update调用减少70%+调用次数
# 项目概览
- **项目类型**: Unity音游编辑器
- **核心框架**: Convention框架 + RScript脚本系统基于FLEE
- **主要系统**:
- ScriptableObject树形更新系统
- Updatement<T>插值系统
- IInteraction多级判定系统
- SplineCore样条线渲染
- TimelineScriptObject时间轴对象
## 技术栈
- Unity 6.2 (6000.2.51)
- C# (支持最新特性)
- Tracy Profiler 0.11.1
- Windows 10+ 专用
⚠️ 警告:永远不要修改此部分 ⚠️
# RIPER-5核心规则摘要
- 必须在响应开头声明当前模式:[MODE: MODE_NAME]
- RESEARCH模式只读取和理解禁止建议和实施
- INNOVATE模式讨论多种方案禁止具体实施
- PLAN模式创建详尽技术规范必须转换为编号清单
- EXECUTE模式只实施已批准计划禁止偏离
- REVIEW模式验证实施与计划的完全一致性
关键原则:
- 未经明确许可不得在模式间转换
- EXECUTE模式必须100%忠实遵循计划
- 标记任何偏差,无论多小
- 使用中文响应(除模式声明和代码)
⚠️ 警告:永远不要修改此部分 ⚠️
# 分析
## 当前架构分析
### 1. Update调用链存在问题
```
GameController.Update()
└─ RootObject.ScriptUpdate()
└─ foreach (child in UpdateChilds)
└─ child.ScriptUpdate() // 递归3,240次
└─ child.UpdateTicks() // 虚函数调用
└─ 具体逻辑
```
**性能问题**
- 递归调用开销累积
- 虚函数调用开销
- 缓存不友好(对象内存分散)
- 无法并行化
- 大量对象在非活跃时间范围内仍被调用
### 2. 现有优化机制(不足)
代码中存在一些优化:
- `UpdatePerFrame`: 降低Update频率
- `IsEnableUpdate`: 静态剪枝(只能剪掉永远不更新的对象)
- Update树剪枝简化单子节点调用链
**不足之处**
- 无法剪枝"暂时不活跃"的对象
- 无法利用多核CPU
- 内存布局对缓存不友好
### 3. 技术约束
- Unity主线程限制Transform等API必须在主线程调用
- MonoBehaviour限制继承自MonoBehaviour的对象管理复杂
## 可用的先进技术
### Windows 10+ 专属优势
1. **SIMD指令集**: AVX2, AVX-512如果CPU支持
2. **现代CPU特性**: 更多核心,更好的缓存
3. **.NET 最新特性**: Span<T>, Memory<T>, stackalloc
4. **Unity DOTS**: ECS + Job System + Burst Compiler
### Unity DOTS技术栈
1. **ECS (Entity Component System)**
- 数据驱动架构
- 缓存友好的内存布局
- 易于并行化
2. **C# Job System**
- 托管的多线程系统
- 自动线程池管理
- 安全检查避免竞态条件
3. **Burst Compiler**
- 将C#编译为高度优化的机器码
- SIMD自动向量化
- 接近C/C++的性能
4. **Collections Package**
- NativeArray, NativeList等非托管集合
- 可在Job中安全使用
- 避免GC压力
### 性能提升潜力
| 技术 | 预期提升 | 适用场景 |
|------|---------|---------|
| 时间范围剪枝 | 3-5倍 | 所有TimelineObject |
| 扁平化调度 | 2-3倍 | Update调用链 |
| Burst编译 | 5-10倍 | 数学密集计算 |
| Job并行 | 2-4倍 | 批量数据处理 |
| 缓存优化 | 2-3倍 | 数据访问模式 |
| **综合** | **30-100倍** | 整体系统 |
# 提议的解决方案
## 方案概览
采用**混合架构**保留MonoBehaviour作为外壳内部使用ECS数据处理。
### 架构设计
```
传统层MonoBehaviour
↓ 数据同步
ECS数据层Burst Job处理
↓ 结果同步
传统层应用到Transform
```
## 核心方案要素
### 1. 时间分片调度系统
**目标**: 只更新活跃时间范围内的对象
**实现**:
- 使用SortedSet维护时间排序
- 激活/停用事件驱动
- 扁平化对象列表(无递归)
**预期**: 减少70%无效Update调用
### 2. ECS化核心系统
#### 2.1 Updatement系统最适合ECS
- 纯数据Entry列表、插值参数
- 纯计算Lerp、曲线求值
- 可完全Burst编译和并行化
#### 2.2 Interaction判定系统
- 输入处理可并行化
- 判定计算可Burst优化
- 结果批量应用
#### 2.3 SplineNode计算
- 样条线计算适合SIMD
- 批量计算所有节点位置
- Burst编译获得巨大提升
### 3. Burst编译的Job
```csharp
[BurstCompile]
public struct UpdatementCalculationJob : IJobParallelFor
{
[ReadOnly] public float CurrentTime;
[ReadOnly] public NativeArray<UpdatementEntry> Entries;
[ReadOnly] public NativeArray<int> ContentIndices;
[WriteOnly] public NativeArray<float3> Results;
public void Execute(int index)
{
// 纯数学计算Burst自动SIMD优化
int content = ContentIndices[index];
float percent = CalculatePercent(CurrentTime, Entries, content);
Results[index] = math.lerp(
Entries[content].Position,
Entries[content + 1].Position,
EvaluateCurve(percent, Entries[content].CurveType)
);
}
}
```
### 4. 内存布局优化
**SoA (Structure of Arrays) 代替 AoS (Array of Structures)**:
```csharp
// 坏AoS缓存不友好
struct UpdatementData {
float timePoint;
Vector3 position;
EaseCurveType curve;
}
UpdatementData[] data; // 数据交错
// 好SoA缓存友好
struct UpdatementDataSoA {
NativeArray<float> timePoints; // 连续
NativeArray<float3> positions; // 连续
NativeArray<byte> curveTypes; // 连续
}
```
### 5. 对象池系统
- 避免GC压力
- 重用NativeArray
- 预分配Job句柄
## 实施分层
### Phase 1: 基础设施1周
1. 时间分片调度器
2. UpdateScheduler基类
3. 基础性能测试框架
### Phase 2: ECS核心2周
1. Updatement系统ECS化
2. Burst Job实现
3. 数据同步机制
### Phase 3: 扩展优化2周
1. SplineNode优化
2. Interaction判定优化
3. 对象池和内存管理
### Phase 4: 深度优化1周
1. SIMD手动优化关键路径
2. 内存布局调优
3. 性能剖析和微调
## 技术细节
### Job依赖管理
```csharp
// 计算Job
JobHandle calcHandle = calculationJob.Schedule(count, 64);
// 应用Job依赖计算Job
JobHandle applyHandle = applyJob.Schedule(calcHandle);
// 等待完成
applyHandle.Complete();
```
### 安全检查
Unity Job System提供编译时和运行时安全检查
- 检测数据竞争
- 验证NativeArray生命周期
- 防止悬空指针
### Profiler集成
保持Tracy Profiler集成
```csharp
using (Profiler.BeginZone("BurstJob.Schedule"))
{
handle = job.Schedule(count, 64);
}
```
## 风险与挑战
### 技术风险
1. **学习曲线**: ECS和Burst需要学习
2. **调试难度**: Burst代码调试较困难
3. **兼容性**: 现有脚本系统集成
### 缓解措施
1. 渐进式迁移,保持向后兼容
2. 完善的性能测试
3. 详细的文档和注释
### 回滚计划
每个Phase完成后打tag必要时可回滚
# 当前执行步骤:
"阶段2.5 - 阶段2整体测试"
# 任务进度
## 阶段1基础设施搭建
### 1.1 创建目录结构
[2025-12-01 17:16:16]
- 已修改:创建目录 Assets/Scripts/Framework/UpdateScheduler/
- 更改新建UpdateScheduler模块目录
- 原因:为扁平化调度器准备代码组织结构
- 阻碍因素:无
- 状态:未确认
### 1.2 创建IUpdateable接口
[2025-12-01 17:17:30]
- 已修改:创建文件 IUpdateable.cs (48行)
- 更改定义IUpdateable接口3个方法和UpdateMode枚举3个值
- 原因为ScriptableObject提供统一的Update接口支持扁平化调度
- 阻碍因素:无
- 状态:未确认
### 1.3 创建UpdateScheduler核心类
[2025-12-01 17:18:45]
- 已修改:创建文件 UpdateScheduler.cs (201行)
- 更改实现完整的扁平化调度器Register、DoUpdate、时间分片、Reset/Clear等
- 原因提供时间分片和扁平化Update管理的核心实现
- 阻碍因素:无
- 状态:未确认
### 1.4 RootObject添加Scheduler字段
[2025-12-01 17:20:15]
- 已修改RootObject.cs (添加1行Line 19)
- 更改添加Scheduler字段并初始化
- 原因为RootObject提供调度器实例
- 阻碍因素:无
- 状态:未确认
### 1.5 RootObject添加清理逻辑
[2025-12-01 17:21:30]
- 已修改RootObject.cs UnloadScript方法 (添加2行Line 38-39)
- 更改在卸载时调用Scheduler.Clear()
- 原因:防止内存泄漏,正确释放注册对象
- 阻碍因素:无
- 状态:未确认
### 1.6 阶段1整体测试
[2025-12-01 17:22:45]
- 已修改阶段1所有代码完成等待测试
- 更改基础设施搭建完成3个新文件RootObject修改2处
- 原因验证阶段1无破坏性影响
- 测试项目:
1. 编译项目 - ✅ 已通过无linter错误
2. 运行编辑器 - ✅ 用户确认成功
3. 打开项目 - ✅ 用户确认成功
4. 检查RootObject.Scheduler字段 - ✅ 用户确认成功
5. 关闭项目 - ✅ 用户确认成功
6. 检查控制台无错误 - ✅ 用户确认成功
- 阻碍因素:无
- 状态:✅ 成功
- Commit: 用户已提交
## 阶段2接口适配
### 2.1 ScriptableObject添加IUpdateable接口声明
[2025-12-01 17:30:00]
- 已修改ScriptableObject.cs 类声明 (Line 582添加IUpdateable接口)
- 更改ScriptableObject实现IUpdateable接口
- 原因使所有ScriptableObject可以被调度器管理
- 阻碍因素:无
- 状态:未确认
### 2.2 添加Update模式字段
[2025-12-01 17:32:15]
- 已修改ScriptableObject.cs (添加3个字段Line 111-116)
- 更改添加_updateMode、_activeStartTime、_activeEndTime字段
- 原因存储对象的Update模式和时间范围
- 阻碍因素:无
- 状态:未确认
### 2.3 添加虚方法供子类重写
[2025-12-01 17:34:30]
- 已修改ScriptableObject.cs (添加2个虚方法Line 175-183)
- 更改添加GetUpdateMode和GetActiveTimeRange虚方法
- 原因允许子类自定义Update模式和时间范围
- 阻碍因素:无
- 状态:未确认
### 2.4 实现IUpdateable接口方法
[2025-12-01 17:36:45]
- 已修改ScriptableObject.cs (添加新的partial class约35行Line 916-950)
- 更改实现IUpdateable的3个接口方法ExecuteUpdate、GetUpdateName、IsUpdateReady
- 原因提供扁平化Update入口复用原有UpdateTicks逻辑
- 阻碍因素:无
- 状态:未确认
### 2.4.1 重命名方法为FlatOptimizationUpdate更具描述性
[2025-12-01 17:40:00]
- 已修改IUpdateable.cs、UpdateScheduler.cs、ScriptableObject.cs
- 更改将方法重命名为FlatOptimizationUpdate明确表达"扁平化优化Update"的含义
- 原因:提高代码可读性,方法名清晰表达优化目的
- 阻碍因素:无
- 状态:未确认
### 2.5 阶段2整体测试
[2025-12-01 17:38:00]
- 已修改阶段2所有代码完成等待测试
- 更改ScriptableObject完整实现IUpdateable接口添加3个字段、2个虚方法、3个接口方法
- 原因:验证接口实现无破坏性影响
- 测试项目:
1. 编译项目 - ✅ 已通过无linter错误
2. 运行编辑器 - 待测试
3. 打开项目 - 待测试
4. 检查Inspector中新增字段是否可见 - 待测试
5. 验证游戏功能不受影响 - 待测试
- 阻碍因素:无
- 状态:未确认 → 等待用户确认:成功/不成功?
# 最终审查
[待完成]