创建仓库
This commit is contained in:
112
设计补丁/ECN_数据模型双态分离与序列化边界的强制隔离.md
Normal file
112
设计补丁/ECN_数据模型双态分离与序列化边界的强制隔离.md
Normal file
@@ -0,0 +1,112 @@
|
||||
---
|
||||
tags: []
|
||||
aliases:
|
||||
- 数据模型双态分离与序列化边界的强制隔离架构设计变更通知 (ECN)
|
||||
date created: 星期一, 十一月 24日 2025, 5:17:58 下午
|
||||
date modified: 星期一, 十一月 24日 2025, 5:20:20 下午
|
||||
---
|
||||
|
||||
# 数据模型双态分离与序列化边界的强制隔离架构设计变更通知 (ECN)
|
||||
|
||||
- **编号**: ECN-2025-002
|
||||
- **主题**: 数据模型双态分离与序列化边界的强制隔离
|
||||
- **适用范围**: 2.5 章节、02_ 核心数据结构、04_ 序列化与网络协议
|
||||
- **关联原则**: [00_ 数据架构总览与原则.md] 第一原则(零拷贝)、第五原则(面向性能布局)
|
||||
- **日期**: 2025-11-24
|
||||
|
||||
---
|
||||
|
||||
## 1. 变更背景与动因 (Background & Motivation)
|
||||
|
||||
### 1.1 现状问题诊断
|
||||
|
||||
在原有的设计文档中(如 `02_核心数据结构.md`),虽然定义了 `TrackData` 等 C++ 结构体,但在 `04_序列化与网络协议.md` 中又引入了 Protobuf 定义。由于缺乏明确的 **“使用边界”** 界定,开发过程中极易出现以下反模式:
|
||||
|
||||
1. **性能杀手**:在计算密集型的内部模块(如 `SignalProcessor`)直接使用 Protobuf 生成的类(Generated Classes)作为数据载体。这会导致无法利用 SIMD 指令集(内存未对齐)、频繁的堆内存分配以及 getter/setter 的调用开销。
|
||||
2. **架构耦合**:内部业务逻辑与外部通信协议强绑定。一旦修改对外接口字段,必须重构内部核心算法代码。
|
||||
3. **零拷贝失效**:Protobuf 的序列化/反序列化本质上是深拷贝操作。如果在内部流水线中过早引入 Protobuf,将直接破坏 [03_ 内存管理与所有权.md] 中建立的零拷贝链路。
|
||||
|
||||
### 1.2 变更目标
|
||||
|
||||
建立 **“双态数据模型 (Dual-State Data Model)”** 架构,强制实施 **“序列化边界 (Serialization Boundary)”** 管控。确保内部数据流专注于**极致计算性能**,外部数据流专注于**互操作性**,两者仅在边界处进行转换。
|
||||
|
||||
---
|
||||
|
||||
## 2. 核心变更规范 (Core Specifications)
|
||||
|
||||
### 2.1 确立“双态数据模型”
|
||||
|
||||
系统中的数据将严格区分为两种互斥的形态:
|
||||
|
||||
|**特征**|**内部原生态 (Internal Native State)**|**外部传输态 (External Wire State)**|
|
||||
|---|---|---|
|
||||
|**承载实体**|**C++ POD Structs** (e.g., `struct TrackData`)|**Protobuf Messages** (e.g., `message TrackDataMessage`)|
|
||||
|**内存布局**|**SIMD 友好** (`alignas(16/32)`,连续内存)|**紧凑编码** (Varint, Tag-Length-Value)|
|
||||
|**生命周期**|**智能指针管理** (`std::unique_ptr` + `MemoryPool`)|**栈上临时对象** 或 **发送缓冲区字节流**|
|
||||
|**适用范围**|`DataReceiver` -> `SignalProcessor` -> `DataProcessor`|`DisplayController` -> `Network` -> `ClientApp`|
|
||||
|**设计原则**|**性能优先** (Raw Performance)|**兼容性优先** (Compatibility)|
|
||||
|
||||
### 2.2 定义“序列化边界” (The Boundary)
|
||||
|
||||
**序列化边界**是指数据从“内部原生态”转换为“外部传输态”的唯一合法逻辑位置。
|
||||
|
||||
- **边界位置**:**仅限于 `DisplayController` (数据网关模块)** 的 `ExecutionEngine` 中。
|
||||
- **流入**:`IDataQueue<DataPacket<std::vector<TrackData>>>` (C++ 对象指针)。
|
||||
- **流出**:`std::string` 或 `std::vector<uint8_t>` (Protobuf 序列化后的二进制流)。
|
||||
- **禁区**:`SignalProcessor` 和 `DataProcessor` **严禁** 引用 `*.pb.h` 头文件,严禁执行 `SerializeToString()` 操作。
|
||||
|
||||
### 2.3 引入“数据映射层” (Data Mapping Layer)
|
||||
|
||||
在边界处(`DisplayController`),引入专门的转换逻辑(Mapper/Adapter),负责将 C++ 结构体字段映射到 Protobuf 消息字段。
|
||||
|
||||
```cpp
|
||||
// 伪代码示例:在边界处的转换逻辑
|
||||
void DisplayController::convertToWireFormat(const std::vector<TrackData>& native_tracks, radar::ipc::TrackDataBatch* proto_batch)
|
||||
{
|
||||
for (const auto& track : native_tracks) {
|
||||
auto* proto_track = proto_batch->add_tracks();
|
||||
|
||||
// 字段映射:从高性能 C++ 结构体 -> Protobuf 消息
|
||||
proto_track->set_track_id(track.track_id);
|
||||
// … 坐标转换、单位换算等 …
|
||||
|
||||
// 注意:此处发生了一次从"页锁定内存"到"网络发送缓冲区"的内存拷贝
|
||||
// 这是为了网络传输格式化所必须付出的代价,但被严格限制在最后一步。
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 对现有文档的修订指引 (Documentation Patch)
|
||||
|
||||
### 3.1 对 `02_核心数据结构.md` 的修正
|
||||
|
||||
- **新增声明**:在文档开头显著位置声明:“本文档定义的结构体为**内部原生态**对象,仅用于模块间的高性能内存交换。这些结构体**不是**网络传输协议。”
|
||||
- **强化定义**:确保 `DetectionResult` 和 `TrackData` 保持纯粹的 POD 特性,移除任何可能暗示序列化的辅助方法(如 `toJson()` 或 `toProto()`),这些方法应移至工具类中。
|
||||
|
||||
### 3.2 对 `04_序列化与网络协议.md` 的修正
|
||||
|
||||
- **明确角色**:明确指出 `.proto` 文件定义的是**外部契约**,而非内部实现。
|
||||
- **新增章节**:添加 **“4.4 序列化边界与映射策略”**,详细描述数据如何在 `DisplayController` 中从 C++ 结构体转换为 Protobuf 消息。
|
||||
|
||||
### 3.3 对 `03_内存管理与所有权.md` 的补充
|
||||
|
||||
- **补充说明**:在零拷贝流程的最后阶段(数据网关),明确说明“零拷贝”在序列化边界处**终止**。序列化过程不可避免地涉及内存读取和重新编码,这是将数据送入网络栈(Socket Buffer)的必要步骤。
|
||||
|
||||
---
|
||||
|
||||
## 4. 优势分析 (Benefits Analysis)
|
||||
|
||||
通过实施此补丁,系统架构将获得以下显著收益:
|
||||
|
||||
1. **计算性能最大化**:内部算法(如卡尔曼滤波、关联矩阵计算)直接操作内存对齐的 C++ 数组,能够充分利用 CPU 的 L1/L2 缓存和 SIMD 指令集,性能相比操作 Protobuf 对象提升 **5-10 倍**。
|
||||
2. **编译依赖解耦**:核心业务模块(`SignalProcessor` 等)不再依赖 Protobuf 库。如果未来更换序列化协议(如从 Protobuf 换为 FlatBuffers),只需修改 `DisplayController` 中的映射层,核心算法代码**零修改**。
|
||||
3. **内存安全屏障**:内部使用强类型的 C++ 结构体,配合 `std::unique_ptr` 管理所有权,消除了直接操作 Protobuf 原始指针可能带来的内存泄漏风险。
|
||||
4. **协议演进灵活性**:内部数据结构可以根据算法需求自由优化(例如添加用于调试的临时字段),而无需修改对外的 `.proto` 契约,只需在映射层忽略这些字段即可,实现了**内外解耦**。
|
||||
|
||||
---
|
||||
|
||||
## 5. 总结
|
||||
|
||||
此 ECN 补丁修正了原设计中关于数据形态的模糊定义,建立了**“内部高性能、外部高兼容、边界严管控”**的数据架构范式。这是将雷达数据处理系统从“原型验证”推向“生产级高性能应用”的关键一步。
|
||||
Reference in New Issue
Block a user