创建仓库
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
---
|
||||
tags:
|
||||
aliases:
|
||||
- 2.6 时序同步与数据一致性 (Timing Synchronization & Data Coherence)
|
||||
date created: 星期一, 十一月 24日 2025, 11:50:10 晚上
|
||||
date modified: 星期一, 十一月 24日 2025, 11:50:24 晚上
|
||||
---
|
||||
|
||||
# 2.6 时序同步与数据一致性 (Timing Synchronization & Data Coherence)
|
||||
|
||||
- **覆盖范围**:定义系统的时间基准获取方式、数据流打点策略以及跨模块处理时的时间对齐逻辑。涵盖从硬件层面的 PTP/GPS 同步,到软件层面的 CPI(相干处理间隔)对齐,以及航迹预测中的时间外推算法,确保系统在微秒级精度下的时空一致性。
|
||||
- **2.6.1 高精度统一时钟源架构 (High-Precision Unified Clock Architecture)**
|
||||
- **核心指向**:定义系统时间的唯一真值来源。优先采用 **PTP (IEEE 1588v2)** 协议通过网口同步至 GPS/北斗授时服务器,实现亚微秒级的时间同步精度。涵盖在 PTP 不可用时的 **NTP 回退策略**,以及利用 CPU **TSC (Time Stamp Counter)** 寄存器作为高频计时源的校准逻辑,防止系统时间跳变(Time Jump)导致的逻辑错误。
|
||||
- **2.6.2 多级数据打点策略 (Multi-Level Timestamping Strategy)**
|
||||
- **核心指向**:定义数据包时间戳的生成位置与精度分级。首选网卡硬件 **TSU (Timestamp Unit)** 生成的入站时间戳(Ingress Timestamp),次选内核网络栈的 `SO_TIMESTAMP` 软件时间戳。在 `DataReceiver` 封装 `RawDataPacket` 时,强制将此硬件/内核时间戳固化为数据的 **“诞生时间” (Generation Time)**,并在后续全链路中保持不变。
|
||||
- **2.6.3 相干处理间隔对齐机制 (CPI Alignment Mechanism)**
|
||||
- **核心指向**:针对信号处理模块的特殊时序要求。定义如何根据雷达 **PRF (脉冲重复频率)** 和 **波位编码**,将连续到达的 UDP 数据包在内存池中重组为严格对齐的 **CPI 数据块**。涵盖处理网络抖动导致的脉冲到达时间波动(Jitter)的缓冲策略,确保 FFT 和多普勒处理时的数据在时间域上严格相干。
|
||||
- **2.6.4 航迹外推与异步测量融合 (Track Extrapolation & Asynchronous Measurement Fusion)**
|
||||
- **核心指向**:针对数据处理模块的时空一致性逻辑。定义在进行数据关联(Data Association)时,如何将上一时刻($t_{k-1}$)的航迹状态,基于运动模型精确外推至当前测量时刻($t_k$)。涵盖处理乱序到达(Out-of-Order)量测数据的**延迟关联**或**丢弃策略**,确保卡尔曼滤波的更新步基于单调递增的时间轴。
|
||||
- **2.6.5 全链路延迟审计与抖动监控 (End-to-End Latency Auditing & Jitter Monitoring)**
|
||||
- **核心指向**:定义系统实时性的度量标准。利用 `DataPacket` 头部携带的诞生时间戳,在流水线的每个关键节点(接收、信号处理完成、航迹更新完成、网关发送)计算 **驻留时间 (Residence Time)**。监控模块需实时统计各阶段的延迟分布,一旦发现处理抖动超过 CPI 周期的一定比例(如 10%),立即触发性能告警或热节流保护。
|
||||
@@ -0,0 +1,114 @@
|
||||
---
|
||||
tags: []
|
||||
date created: 星期三, 十一月 26日 2025, 9:41:51 晚上
|
||||
date modified: 星期三, 十一月 26日 2025, 9:54:07 晚上
|
||||
---
|
||||
|
||||
# 2.6.1 高精度统一时钟源架构 (High-Precision Unified Clock Architecture)
|
||||
|
||||
**基线核心宗旨**:**“Hardware PTP as Truth, Software TSC for Speed (硬件 PTP 为真值,软件 TSC 为速度)”**。
|
||||
我们构建一个分层的时间架构:底层依赖 **IEEE 1588v2 (PTP)** 锁定物理时钟,应用层利用 **CPU TSC** 实现零系统调用的纳秒级打点,并通过**动态校准回路**将两者对齐。
|
||||
|
||||
-----
|
||||
|
||||
## 1. 约束输入与对齐 (Constraints & Alignment)
|
||||
|
||||
基于分布式雷达组网(TDP-2.4-DIST)和实时性要求,我们需对齐以下硬性约束:
|
||||
|
||||
1. **同步精度 (P0)**:多站协同要求时间同步误差 **\< 1µs**。传统的 NTP(毫秒级)无法满足,必须使用硬件辅助的 PTP。
|
||||
2. **硬件依赖 (Hardware)**:
|
||||
- **网卡**:必须支持 **Hardware Timestamping** (IEEE 1588 PHY)。(需确认您的网迅网卡或采集卡是否支持,若不支持需回退到软件 PTP,精度降至 10-100µs)。
|
||||
- **交换机**:局域网交换机应支持 **PTP Transparent Clock (TC)** 或 **Boundary Clock (BC)** 模式,以消除排队抖动。
|
||||
3. **单调性 (Monotonicity)**:系统内部逻辑(如卡尔曼滤波 `dt` 计算)严禁出现“时光倒流”。即使外部时钟源发生跳变(Step),内部时钟也必须平滑过渡(Slew)。
|
||||
|
||||
-----
|
||||
|
||||
## 2. 权衡分析与选项呈现 (Trade-off Matrix)
|
||||
|
||||
### 议题 1:同步协议栈选型
|
||||
|
||||
| 选项 | A. NTP (Network Time Protocol) | B. Software PTP | C. Hardware PTP **(推荐)** |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **机制** | 纯软件协议,通过统计学算法消除抖动。 | 使用 PTP 协议,但打点在驱动层/协议栈层。 | **PHY 芯片打点**。完全消除 OS 调度和协议栈延迟。 |
|
||||
| **精度** | 1ms - 10ms。 | 10µs - 100µs。 | **\< 1µs (亚微秒级)**。 |
|
||||
| **适用性** | 日志记录、非实时业务。 | 低成本组网。 | **相控阵雷达、高频交易、工业自动化**。 |
|
||||
|
||||
### 议题 2:应用层计时源 (Application Timing Source)
|
||||
|
||||
| 选项 | A. `clock_gettime` (vDSO) | B. `rdtsc` 指令 (TSC) **(推荐)** |
|
||||
| :--- | :--- | :--- |
|
||||
| **机制** | Linux 标准 API,读取内核维护的时间结构体。 | 直接读取 CPU 内部的 Time Stamp Counter 寄存器。 |
|
||||
| **开销** | **低 (\~20-50ns)**。vDSO 避免了陷入内核,但仍有内存访问开销。 | **极低 (\~5-10ns)**。纯寄存器操作,流水线几乎无停顿。 |
|
||||
| **缺陷** | 仍有微小开销,且受制于内核的时钟更新策略。 | **原生不支持绝对时间**。TSC 只是一个开机后的滴答计数,且不同 CPU 核之间可能微弱不同步(现代 CPU 已通过 `constant_tsc` 解决)。 |
|
||||
| **结论** | 通用场景首选。 | **高频热路径(如每秒百万次打点)首选**。需配合软件校准。 |
|
||||
|
||||
-----
|
||||
|
||||
## 3. 基线确立与实施规范
|
||||
|
||||
为了达成亚微秒级同步并支持高频打点,我们确立 **Hardware PTP + TSC 软时钟** 为基线。
|
||||
|
||||
### 3.1. 物理层同步架构 (PTP Topology)
|
||||
|
||||
- **Grandmaster (GM)**:总控服务器或专用的 GPS/北斗授时仪,作为 PTP 主时钟。
|
||||
- **Slave Nodes**:雷达处理服务器(DataReceiver 所在节点)。
|
||||
- **软件栈**:使用 Linux 标准工具集 **`linuxptp`**。
|
||||
- **`ptp4l`**:负责将 **网卡 PHC (PTP Hardware Clock)** 同步到 GM。
|
||||
- **`phc2sys`**:负责将 **系统时钟 (System Clock / CLOCK\_REALTIME)** 同步到 网卡 PHC。
|
||||
|
||||
**运维配置基线 (`/etc/linuxptp/ptp4l.conf`)**:
|
||||
|
||||
```txt
|
||||
[global]
|
||||
time_stamping hardware
|
||||
delay_mechanism E2E
|
||||
network_transport UDPv4
|
||||
# 关键:在锁定前允许跳变,锁定后仅微调
|
||||
step_threshold 1.0
|
||||
first_step_threshold 0.00002
|
||||
```
|
||||
|
||||
## 2. 应用层软时钟设计 (TSC-based Soft Clock)
|
||||
|
||||
在 C++ 应用层,我们封装一个 `HighPrecisionClock` 类,利用 TSC 提供极速时间戳,同时后台线程负责将其“锚定”到 PTP 时间上。
|
||||
|
||||
- **核心原理**:
|
||||
|
||||
$$
|
||||
T_{current} = T_{base} + \frac{(TSC_{current} - TSC_{base})}{Frequency}$$
|
||||
|
||||
* $T_{base}$ 和 $TSC_{base}$ 是最近一次校准时的基准对。
|
||||
* $Frequency$ 是 CPU 主频(需通过校准测得精确值,而非标称值)。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
* **校准线程 (Calibration Thread)**:
|
||||
- **频率**:每 1 秒运行一次。
|
||||
- **逻辑**:
|
||||
1. 原子操作同时读取当前 `clock_gettime(REALTIME)` ($T_{new}$) 和 `rdtsc` ($TSC_{new}$)。
|
||||
2. 更新全局原子变量 `BasePair` = {$T_{new}$, $TSC_{new}$}。
|
||||
3. **平滑策略**:如果发现 PTP 时间发生了跳变(Step),不要立即更新 $T_{base}$ 导致时间倒流,而是调整 $Frequency$ 让时间“快跑”或“慢跑”以追赶(Slew),保证单调性。
|
||||
|
||||
### 3. 异常处理与回退 (Fallback)
|
||||
|
||||
- **PTP 失锁检测**:监控模块需监听 `ptp4l` 的 `rms` (Root Mean Square) 偏差值。
|
||||
- 若 `rms > 10µs` 持续 5 秒,标记 **"Time Sync Degraded"**。
|
||||
- **NTP 回退**:如果 PTP 完全不可用(网卡不支持或链路故障),自动回退到 NTP。
|
||||
- **实现**:`chronyd` 配置 `noselect`,仅当 PTP 服务停止时接管。
|
||||
- **标记**:此时数据包中的 `timestamp_us` 精度下降,`TrackDataBatch` 的状态字段应置位 `TIME_PRECISION_LOW`。
|
||||
|
||||
-----
|
||||
|
||||
## 总结:2.6.1 基线图谱
|
||||
|
||||
| 组件 | 核心基线 | 关键技术点 |
|
||||
| :--- | :--- | :--- |
|
||||
| **时间源 (Truth)** | **GPS/北斗 -\> PTP GM** | 绝对时间真值。 |
|
||||
| **同步协议** | **IEEE 1588v2 (Hardware)** | `ptp4l` + `phc2sys`,亚微秒精度。 |
|
||||
| **应用层 API** | **TSC Soft Clock** | `rdtsc` + 动态校准,纳秒级开销。 |
|
||||
| **单调性保障** | **软件平滑 (Slewing)** | 禁止时间倒流,通过频率微调消除偏差。 |
|
||||
|
||||
**提问**:您是否确认 **“硬件 PTP 同步 + TSC 软时钟封装”** 的架构基线?如果确认,我们将进入 **2.6.2 多级数据打点策略**,定义这个高精度时间戳具体“打”在哪里。
|
||||
@@ -0,0 +1,125 @@
|
||||
---
|
||||
tags: []
|
||||
date created: 星期三, 十一月 26日 2025, 9:49:46 晚上
|
||||
date modified: 星期三, 十一月 26日 2025, 10:06:18 晚上
|
||||
---
|
||||
|
||||
# 2.6.2 多级数据打点策略 (Multi-Level Timestamping Strategy)
|
||||
|
||||
**基线核心宗旨**:**“As Early As Possible (越早越好)”**。
|
||||
时间戳必须尽可能在物理层(PHY)或链路层(MAC)生成,以消除操作系统中断调度、驱动处理和协议栈拷贝带来的**不定长抖动(Jitter)**。
|
||||
|
||||
-----
|
||||
|
||||
## 1. 约束输入与对齐 (Constraints & Alignment)
|
||||
|
||||
基于 2.1.1 审计结果(网迅 WX1860AL4 网卡)和 2.6.1 确立的时钟基线,我们需要对齐以下约束:
|
||||
|
||||
1. **硬件能力 (Hardware Cap)**:
|
||||
- **网迅 NIC**:需确认驱动是否支持 `SO_TIMESTAMPING` 接口读取硬件 RX 时间戳。通常企业级网卡(Intel X710/Mellanox)均支持,国产网卡需实测验证。若不支持,需回退到内核软打点。
|
||||
2. **协议支持 (Protocol)**:
|
||||
- UDP 数据包本身不携带“发送时间”(除非应用层协议写了)。因此我们依赖的是**接收端打点 (Ingress Timestamping)**。
|
||||
3. **数据结构关联**:
|
||||
- 生成的纳秒级时间戳必须填入 `RawDataPacket` 的 Header,并最终映射到 Protobuf 的 `timestamp_us`。
|
||||
|
||||
-----
|
||||
|
||||
## 2. 权衡分析与选项呈现 (Trade-off Matrix)
|
||||
|
||||
我们按照“离物理线路的距离”定义三个打点层级:
|
||||
|
||||
| 选项 | A. 用户态打点 (User-space) | B. 内核软打点 (Kernel SW) **(基线)** | C. 硬件硬打点 (Hardware HW) **(理想)** |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **生成位置** | `recvmsg()` 返回后的应用层代码。 | 网卡驱动收到中断,SKB (Socket Buffer) 创建时刻。 | 网卡 PHY 芯片接收到前导码(Preamble)时刻。 |
|
||||
| **抖动来源** | **极大**。受 CPU 调度、软中断处理、内存拷贝影响,抖动可达 10-100µs。 | **中等**。受中断响应延迟影响,抖动约 1-10µs。 | **极小**。几乎无抖动 (\< 100ns)。 |
|
||||
| **PTP 依赖** | 依赖系统时钟 (`CLOCK_REALTIME`)。 | 依赖系统时钟。 | 依赖网卡 PHC (PTP Hardware Clock) 与系统时钟的同步 (`phc2sys`)。 |
|
||||
| **实现复杂度**| 低。调用 `Clock::now()` 即可。 | 中。需配置 Socket 选项并解析辅助数据 (`CMSG`)。 | 高。需硬件支持,且需处理 PHC 到 UTC 的转换。 |
|
||||
| **适用场景** | 功能调试、非实时业务。 | **当前国产环境最稳妥的基线**。 | 相控阵雷达、高频交易。 |
|
||||
|
||||
-----
|
||||
|
||||
## 3. 基线确立与实施规范
|
||||
|
||||
考虑到国产网卡驱动的成熟度风险,我们确立 **“优先硬件,兜底内核,严禁用户态”** 的分级策略。
|
||||
|
||||
### 3.1 策略分级定义 (Hierarchy Definition)
|
||||
|
||||
- **Priority 1 (HW)**: 尝试启用 **`SO_TIMESTAMPING_RX_HARDWARE`**。
|
||||
- 如果网卡支持,这是绝对真值。
|
||||
- *注意*:硬件时间戳通常是 PHC 时间(TAI),需在用户态根据 `ptp4l` 的 offset 转换为 UTC。
|
||||
- **Priority 2 (SW)**: 回退到 **`SO_TIMESTAMPNS`** (内核接收时间)。
|
||||
- 这是**工程基线**。它反映了数据包进入 Linux 网络栈的第一时间点,消除了应用程序调度的延迟。
|
||||
- **Priority 3 (App)**: **严禁作为生产标准**。仅在上述两者皆失败时,使用 2.6.1 定义的 `HighPrecisionClock::now()` 补救,并标记数据质量为 `LOW_PRECISION`。
|
||||
|
||||
### 3.2 实现规范:辅助数据解析 (CMSG Parsing)
|
||||
|
||||
在 `DataReceiver` 的 I/O 线程中,必须改造 `recvmmsg` 的调用方式,以提取内核附带的时间戳元数据。
|
||||
|
||||
- **Socket 配置**:
|
||||
|
||||
```cpp
|
||||
int flags = SO_TIMESTAMPNS; // 请求内核软件时间戳 (纳秒级)
|
||||
// 如果确认网卡支持硬件打点,则改为:
|
||||
// int flags = SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_RAW_HARDWARE;
|
||||
setsockopt(sockfd, SOL_SOCKET, SO_TIMESTAMPING, &flags, sizeof(flags));
|
||||
```
|
||||
|
||||
- **接收逻辑 (核心代码范式)**:
|
||||
|
||||
```cpp
|
||||
void UdpReceiver::receiveLoop() {
|
||||
struct mmsghdr msgs[BATCH_SIZE];
|
||||
struct iovec iovecs[BATCH_SIZE];
|
||||
char cmsg_buf[BATCH_SIZE][256]; // 存放辅助数据的缓冲区
|
||||
|
||||
// … 初始化 msgs, iovecs, cmsg …
|
||||
|
||||
int n = recvmmsg(sockfd, msgs, BATCH_SIZE, 0, nullptr);
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
uint64_t timestamp_ns = 0;
|
||||
|
||||
// 解析辅助数据 (Control Message)
|
||||
struct cmsghdr *cmsg;
|
||||
for (cmsg = CMSG_FIRSTHDR(&msgs[i].msg_hdr); cmsg; cmsg = CMSG_NXTHDR(&msgs[i].msg_hdr, cmsg)) {
|
||||
// 优先提取硬件时间戳,若无则提取软件时间戳
|
||||
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMPNS) {
|
||||
struct timespec *ts = (struct timespec *)CMSG_DATA(cmsg);
|
||||
timestamp_ns = ts->tv_sec * 1000000000ULL + ts->tv_nsec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 兜底:如果内核没给时间戳,立刻用 TSC 软时钟打点
|
||||
if (timestamp_ns == 0) {
|
||||
timestamp_ns = HighPrecisionClock::now();
|
||||
}
|
||||
|
||||
// 固化:写入 RawDataPacket Header
|
||||
// 这一刻起,这个时间戳就是数据的"法定出生时间"
|
||||
auto packet = MakePacket(std::move(payload), seq_id);
|
||||
packet.header.timestamp_us = timestamp_ns / 1000;
|
||||
// … 推送队列 …
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 全链路时间戳传递 (Propagation)
|
||||
|
||||
这个“出生时间戳” (`timestamp_us`) 必须在系统中神圣不可侵犯:
|
||||
|
||||
- **接收端 (`DataReceiver`)**:生成并写入 `RawDataPacket.header`。
|
||||
- **处理端 (`SignalProcessor`)**:继承该时间戳。虽然 FFT 处理是在 5ms 后进行的,但数据的物理意义依然是“那个时刻的回波”。
|
||||
- **输出端 (`DisplayController`)**:将该时间戳写入 Protobuf 的 `timestamp_us` 字段发送给显控。
|
||||
- *注意*:显控端看到的延迟 = `Now() - timestamp_us`。这个延迟包含了:`内核排队 + 信号处理耗时 + 航迹关联耗时 + 序列化耗时 + 网络传输耗时`。这正是我们想要的**真实物理延迟**。
|
||||
|
||||
-----
|
||||
|
||||
## 总结:2.6.2 基线图谱
|
||||
|
||||
| 维度 | 核心基线 | 技术细节 |
|
||||
| :--- | :--- | :--- |
|
||||
| **打点源** | **内核软打点 (`SO_TIMESTAMPNS`)** | 兼顾精度与兼容性,消除用户态抖动。 |
|
||||
| **理想源** | **硬件打点 (HW RX)** | 若网卡支持,优先升级至此 (需实测)。 |
|
||||
| **获取方式** | **`recvmmsg` + `CMSG`** | 从 Socket 辅助数据中提取,而非调用 `time()`。 |
|
||||
| **语义** | **生成时间 (Generation Time)** | 代表信号到达系统的物理时刻,全链路透传,禁止修改。 |
|
||||
146
系统基座文件/2/2.6/2.6.3 相干处理间隔对齐机制 (CPI Alignment Mechanism).md
Normal file
146
系统基座文件/2/2.6/2.6.3 相干处理间隔对齐机制 (CPI Alignment Mechanism).md
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
tags: []
|
||||
date created: 星期三, 十一月 26日 2025, 10:25:55 晚上
|
||||
date modified: 星期三, 十一月 26日 2025, 10:28:06 晚上
|
||||
---
|
||||
|
||||
# 2.6.3 相干处理间隔对齐机制 (CPI Alignment Mechanism)
|
||||
|
||||
-----
|
||||
|
||||
## TL;DR
|
||||
|
||||
本节确立了 **“原地乱序重组 (In-Place Scatter Assembly)”** 的基线策略。
|
||||
利用 **脉冲索引 (Pulse Index)** 直接计算内存偏移量,将网络包数据直接写入预分配的页锁定内存(Pinned Memory),实现**零拷贝组装**。配合 **“空间/时间双重触发”** 的提交机制和 **“有限零填充”** 的容错策略,在抗网络抖动与保障实时性之间取得平衡。
|
||||
|
||||
-----
|
||||
|
||||
## 一、 约束输入与对齐 (Constraints & Alignment)
|
||||
|
||||
基于前序章节(2.1, 2.2, 2.6.2),我们面临以下硬性约束:
|
||||
|
||||
1. **数据形态**:
|
||||
- **输入**:UDP JUMBO Frame (9KB)。每个包可能包含 1 个或多个脉冲的回波数据,带有 `BatchID` (CPI ID) 和 `PulseIndex`。
|
||||
- **输出**:符合 **2.2.6** 定义的显存布局 `[Channel][Pulse][Range]` (Padding 对齐)。
|
||||
2. **时序特性**:
|
||||
- 网络抖动(Jitter)客观存在,数据包到达顺序不一定严格均等。
|
||||
- 算法要求:多普勒处理(FFT)要求脉冲间隔(PRI)是均匀的。如果数据包晚到,我们不能“等”太久,否则会阻塞流水线;如果包丢了,矩阵就“穿孔”了。
|
||||
3. **内存模型**:必须在 **2.2.1** 确立的 `MemoryPool`(页锁定内存)中直接操作,避免额外的 `memcpy`。
|
||||
|
||||
-----
|
||||
|
||||
## 二、 权衡分析与选项呈现 (Trade-off Matrix)
|
||||
|
||||
### 议题 1:组装策略 (Assembly Strategy)
|
||||
|
||||
| 选项 | A. 顺序追加 + 排序 (Append & Sort) | B. 原地乱序重组 (In-Place Scatter) **(推荐)** |
|
||||
| :--- | :--- | :--- |
|
||||
| **机制** | 收到一个包就 push\_back 到 buffer,凑够数量后按 `PulseIndex` 排序整理内存。 | 根据包头的 `PulseIndex` 直接计算目标地址偏移 `offset`,写入最终位置。 |
|
||||
| **内存拷贝** | **2 次** (接收 -\>临时 Buf-\>排序后 Buf)。 | **1 次** (接收 -\>最终 Buf)。 |
|
||||
| **乱序容忍** | 好,但整理开销大。 | **极佳**。先到的包占坑,后到的包填坑,无视顺序。 |
|
||||
| **CPU 开销** | 高 (排序算法)。 | **极低** (O(1) 地址计算)。 |
|
||||
|
||||
### 议题 2:CPI 提交触发机制 (Commit Trigger)
|
||||
|
||||
| 选项 | A. 严格计数触发 (Strict Count) | B. 严格时间触发 (Strict Timer) | C. 混合双触发 (Hybrid) **(推荐)** |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **机制** | 必须收齐 N 个脉冲才提交。少一个就死等。 | 无论收多少,每隔 T 毫秒强制提交一次。 | **收齐 N 个** OR **首包到达后超时 T\_max**,满足其一即提交。 |
|
||||
| **实时性** | **差**。一个包丢了会导致该 CPI 永远卡死,甚至阻塞后续 CPI。 | **中**。可能切断正在传输的完整 CPI。 | **高**。既保证了完整性,又防止了死锁。 |
|
||||
| **丢包处理** | 无法处理。 | 截断。 | **自适应**。超时未齐则标记为“残缺 CPI”。 |
|
||||
|
||||
### 议题 3:残缺数据处理 (Incomplete Data Policy)
|
||||
|
||||
当触发超时提交时,CPI 矩阵中会有“空洞”(丢包导致的缺失脉冲)。
|
||||
|
||||
| 选项 | A. 整块丢弃 (Drop All) | B. 零填充 (Zero Padding) **(推荐)** |
|
||||
| :--- | :--- | :--- |
|
||||
| **机制** | 只要不完整,整个 CPI 扔掉。 | 缺失的脉冲位置填 0,强行送入 GPU。 |
|
||||
| **算法影响** | **断续**。航迹会中断,但没噪音。 | **信噪比下降**。FFT 旁瓣升高,可能产生假目标。 |
|
||||
| **工程价值** | 简单,适合严苛场景。 | **鲁棒**。偶尔丢 1-2 个包不影响大局,通过 CFAR 阈值抑制旁瓣。 |
|
||||
|
||||
-----
|
||||
|
||||
## 三、 基线确立与实施规范
|
||||
|
||||
为了在 1GbE 的物理限制下榨干性能,我们确立 **B. 原地乱序重组** + **C. 混合双触发** 为基线。
|
||||
|
||||
### 1\. 数据结构:智能 CPI 容器 (`AssemblyBuffer`)
|
||||
|
||||
我们在 `DataReceiver` 中维护一个“正在组装”的 CPI 池。
|
||||
|
||||
```cpp
|
||||
struct AssemblyBuffer {
|
||||
// 基础元数据
|
||||
uint64_t batch_id = 0;
|
||||
uint64_t first_packet_time_us = 0; // 首包到达时间 (用于超时判定)
|
||||
uint32_t packets_received = 0; // 已收包计数
|
||||
uint32_t total_packets_expected = 0; // 预期总包数 (由波位参数决定)
|
||||
|
||||
// 内存指针 (指向 MemoryPool 中的一块 Pinned Memory)
|
||||
// 物理布局严格遵循 [Channel][Pulse][Range]
|
||||
Complex* data_ptr = nullptr;
|
||||
|
||||
// 位图 (Bitmap):用于快速标记哪些 Pulse 已经收到了
|
||||
// 相比 vector<bool> 更快,且方便检查完整性
|
||||
std::bitset<MAX_PULSES_PER_CPI> reception_mask;
|
||||
|
||||
// 状态
|
||||
enum State { IDLE, ASSEMBLING, READY, DAMAGED };
|
||||
State state = IDLE;
|
||||
};
|
||||
```
|
||||
|
||||
### 2\. 原地重组逻辑 (In-Place Assembly Logic)
|
||||
|
||||
这是 **I/O 线程** 的核心循环逻辑:
|
||||
|
||||
1. **接收**:`recvmmsg` 收到一个 UDP 包。
|
||||
2. **解析**:读取包头,获取 `BatchID` (CPI ID) 和 `PulseIndex`。
|
||||
3. **寻址**:
|
||||
- 若 `BatchID` 是新的,从 `MemoryPool` 申请一块新 `AssemblyBuffer`。
|
||||
- 若 `BatchID` 已存在,命中缓存。
|
||||
4. **计算偏移 (关键)**:
|
||||
- 利用 **2.2.6** 确定的 Pitch (行对齐步长)。
|
||||
- `TargetAddr = BufferBase + (PulseIndex * Pitch_Bytes)`。
|
||||
5. **写入**:将 UDP Payload 直接 `memcpy` 到 `TargetAddr`。
|
||||
- *注*:这是数据进入系统的**唯一一次拷贝**。
|
||||
6. **标记**:`reception_mask.set(PulseIndex)`;`packets_received++`。
|
||||
|
||||
### 3\. 提交与超时策略 (Commit & Timeout)
|
||||
|
||||
我们需要一个**低频**(如 1kHz)的检查器(可以在 I/O 线程的空闲间隙运行,或由定时器触发):
|
||||
|
||||
- **完整性检查**:`if (packets_received == total_packets_expected)` -\> **立即提交** (Push to GPU Queue)。
|
||||
- **超时检查**:`if (Now() - first_packet_time_us > MAX_JITTER_WINDOW_US)` -\> **强制提交**。
|
||||
- *基线值*:`MAX_JITTER_WINDOW_US` 建议设为 **CPI 时长的 10%**(例如 CPI 为 5ms,则抖动容忍窗为 500us)。
|
||||
|
||||
### 4\. 容错与填充规范
|
||||
|
||||
当 **强制提交** 发生时(即丢包):
|
||||
|
||||
- **丢包率判定**:
|
||||
- 若 `LossRate < 5%` (如 128 个脉冲丢了 \< 6 个):执行 **零填充 (Zero Padding)**。将 `reception_mask` 中为 0 的位置对应的内存置零(`memset`)。标记数据质量为 `DEGRADED`。
|
||||
- 若 `LossRate >= 5%`:**整块丢弃**。FFT 在缺失大量数据时结果不可信。记录 `WARNING` 日志。
|
||||
|
||||
-----
|
||||
|
||||
## 四、 自我反驳与边界修正 (Self-Rebuttal)
|
||||
|
||||
- **反驳 1**:原地乱序重组需要预知 `PulseIndex`,如果 UDP 包头里没有这个字段怎么办?
|
||||
- *修正*:协议层(2.1.2)必须强制要求 FPGA/DPU 打包时带上 `PulseIndex`。如果前端不可控,则必须在 `DataReceiver` 维护一个软件计数器,但这会失去抗乱序能力,属于**降级方案**。
|
||||
- **反驳 2**:`memset` 清零操作在大内存(如 64MB)下也是耗时的。
|
||||
- *修正*:我们使用了 `MemoryPool`。在归还 Block 时,是否需要清零?不,我们在**申请 Block 时不清零**,而是依赖**全覆盖写入**。因此,对于没收到的脉冲,**必须显式清零**,否则会残留上一个 CPI 的脏数据(鬼影目标)。
|
||||
- *优化*:只对 `reception_mask` 为 0 的那些行(Pitch)做 `memset`,而不是整个 Buffer。
|
||||
|
||||
-----
|
||||
|
||||
## 总结:2.6.3 基线图谱
|
||||
|
||||
| 维度 | 核心基线 | 关键技术点 |
|
||||
| :--- | :--- | :--- |
|
||||
| **组装模式** | **In-Place Scatter (原地乱序)** | `Addr = Base + PulseIdx * Pitch`,O(1) 复杂度。 |
|
||||
| **内存操作** | **Single Copy (单次拷贝)** | 从 UDP 接收缓冲区直接到 Pinned Memory。 |
|
||||
| **提交触发** | **Hybrid (满额即发 / 超时强发)** | 抖动窗口建议为 CPI 时长的 10%。 |
|
||||
| **容错策略** | **Conditional Padding (条件填充)** | 丢包 \< 5% 补零;\> 5% 丢弃。需显式清除脏数据。 |
|
||||
|
||||
-----
|
||||
@@ -0,0 +1,164 @@
|
||||
---
|
||||
tags: []
|
||||
date created: 星期三, 十一月 26日 2025, 10:30:58 晚上
|
||||
date modified: 星期三, 十一月 26日 2025, 10:48:13 晚上
|
||||
---
|
||||
|
||||
# 2.6.4 航迹外推与异步测量融合 (Track Extrapolation & Asynchronous Measurement Fusion)
|
||||
|
||||
-----
|
||||
|
||||
这是数据处理模块(DataProcessor)的**时空校准器**。
|
||||
在 2.6.2 中,我们给每个 CPI 数据打上了高精度的“出生时间戳” ($t_{meas}$)。
|
||||
在 2.6.3 中,我们完成了数据的物理拼装。
|
||||
现在,算法核心面临的问题是:**当前的航迹停留在 $t_{track}$ 时刻,而新来的量测数据产生于 $t_{meas}$ 时刻。两者在时间上不对齐,如何在空间上进行关联?**
|
||||
|
||||
对于相控阵雷达,波束调度是灵活的,数据到达是异步的,传统的“按扫描周期(Scan-based)”更新逻辑已经失效,必须转向 **“按量测驱动(Measurement-Driven)”** 的异步滤波机制。
|
||||
|
||||
-----
|
||||
|
||||
## 一、 约束输入与对齐 (Constraints & Alignment)
|
||||
|
||||
基于前序基线,我们面临以下硬性约束:
|
||||
|
||||
1. **时间真值**:所有计算必须基于 **2.6.2** 确立的 `timestamp_us`(物理生成时间)。严禁使用 `Now()`(处理时间)进行滤波,否则会将“处理延迟”和“排队延迟”错误地耦合进运动模型,导致速度估计偏差。
|
||||
2. **数据单调性**:物理世界的时间是单调递增的。但网络传输可能导致 UDP 包乱序,使得 $t_{meas}$ 偶尔出现回退。
|
||||
3. **计算模型**:内部对象遵循 **2.5.1** 定义的 `TrackData` (POD, `float state[8]`)。
|
||||
|
||||
-----
|
||||
|
||||
## 二、 权衡分析与选项呈现 (Trade-off Matrix)
|
||||
|
||||
### 议题 1:时间对齐策略 (Alignment Strategy)
|
||||
|
||||
| 选项 | A. 统一同步到当前时刻 (Sync to Now) | B. 航迹外推到量测时刻 (Extrapolate to Meas) **(推荐)** |
|
||||
| :--- | :--- | :--- |
|
||||
| **机制** | 将所有航迹和新量测都外推到 `Now()` 或固定的 `T_tick`,在同一时间切片上做关联。 | 保持量测不动(因为它是真值),将航迹状态外推 $\Delta t = t_{meas} - t_{track}$,在 $t_{meas}$ 处做关联。 |
|
||||
| **精度** | **中**。引入了“处理延迟”的外推误差。 | **高**。利用了最原始的测量时间,物理意义最严谨。 |
|
||||
| **适用性** | 机械扫描雷达(整圈更新)。 | **相控阵雷达/异步多传感器融合**。 |
|
||||
| **副作用** | 航迹时间戳随系统时钟更新。 | 航迹时间戳随量测时间更新。 |
|
||||
|
||||
### 议题 2:乱序量测处理 (OOSM - Out of Sequence Measurement)
|
||||
|
||||
当 $t_{meas} < t_{track}$ 时(即新收到的数据比航迹当前状态还老):
|
||||
|
||||
| 选项 | A. 状态回溯滤波 (Retrodiction) | B. 缓冲重排 (Buffering) | C. 直接丢弃 (Drop) **(推荐)** |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **机制** | 保存历史状态快照,回滚到 $t_{meas}$ 更新后再推回来。 | 在接收端设置缓冲窗(如 50ms),排序后再送入算法。 | **拒收**“来自过去”的数据。 |
|
||||
| **复杂度** | **极高**。内存和计算开销翻倍。 | **中**。增加系统整体延迟。 | **极低**。 |
|
||||
| **适用性** | 数据极稀疏的场景(如空管雷达)。 | 对延迟不敏感的离线系统。 | **高更新率雷达**。丢掉一帧数据对跟踪影响微乎其微。 |
|
||||
|
||||
-----
|
||||
|
||||
## 三、 基线确立与实施规范
|
||||
|
||||
为了适配相控阵体制并保证微秒级一致性,我们确立 **B. 航迹外推到量测时刻** + **C. 直接丢弃乱序** 为基线。
|
||||
|
||||
### 1\. 核心算法:异步外推更新 (Asynchronous Update)
|
||||
|
||||
在关联阶段(Association),针对每一个待匹配的航迹 $Tr_i$,执行以下逻辑:
|
||||
|
||||
1. **时间差计算 (Time Difference)**
|
||||
|
||||
计算量测时间 ($t_{meas}$) 与当前航迹时间 ($t_{track}$) 的偏差,转换为秒:
|
||||
|
||||
$$
|
||||
\Delta t = (t_{meas} - t_{track}) \times 10^{-6}
|
||||
$$
|
||||
|
||||
- $t_{meas}$: 新到达的量测数据时间戳 (单位: 微秒)
|
||||
- $t_{track}$: 航迹当前状态的时间戳 (单位: 微秒)
|
||||
|
||||
2. **状态外推方程 (State Extrapolation)**
|
||||
|
||||
基于时间差 $\Delta t$ 将航迹状态向前推演:
|
||||
|
||||
$$
|
||||
\hat{x}_{k|k-1} = F(\Delta t) \cdot \hat{x}_{k-1|k-1}
|
||||
$$
|
||||
|
||||
- $\hat{x}_{k|k-1}$: 外推后的预测状态向量
|
||||
- $F(\Delta t)$: 状态转移矩阵 (如 CV/CA 模型,随 $\Delta t$ 变化)
|
||||
- $\hat{x}_{k-1|k-1}$: 上一时刻的更新状态
|
||||
|
||||
3. **残差计算 (Innovation Calculation)**
|
||||
|
||||
计算实际量测值与预测观测值之间的差异:
|
||||
|
||||
$$
|
||||
\tilde{y} = z_{meas} - H \cdot \hat{x}_{k|k-1}
|
||||
$$
|
||||
|
||||
- $\tilde{y}$: 修正后的残差 (Innovation)
|
||||
- $z_{meas}$: 转换后的笛卡尔坐标量测值
|
||||
- $H$: 观测矩阵
|
||||
|
||||
---
|
||||
|
||||
### 3\. 代码实现范式 (C++ Optimized)
|
||||
|
||||
利用 2.5.1 定义的定长数组和 SIMD 对齐特性:
|
||||
|
||||
```cpp
|
||||
// 2.5.1 TrackData (State[8]: x, y, z, vx, vy, vz, pad, pad)
|
||||
// 2.5.1 DetectionResult (Block 0: r, azi, ele, v)
|
||||
|
||||
void KalmanFilter::predictAndAssociate(TrackData& track, const DetectionResult& meas) {
|
||||
// 1. 时间对齐 (使用 2.6.2 定义的硬件/内核时间戳)
|
||||
int64_t dt_us = (int64_t)meas.timestamp_us - (int64_t)track.timestamp_us;
|
||||
|
||||
// 2. OOSM 保护 (基线:丢弃乱序)
|
||||
if (dt_us <= 0) return;
|
||||
|
||||
float dt = dt_us * 1e-6f;
|
||||
|
||||
// 3. 状态外推 (CV 模型示例) - SIMD 友好
|
||||
// x' = x + vx * dt
|
||||
// vx' = vx
|
||||
float predicted_state[8];
|
||||
|
||||
// 手动展开循环或利用编译器自动向量化
|
||||
predicted_state[0] = track.state[0] + track.state[3] * dt; // x
|
||||
predicted_state[1] = track.state[1] + track.state[4] * dt; // y
|
||||
predicted_state[2] = track.state[2] + track.state[5] * dt; // z
|
||||
predicted_state[3] = track.state[3]; // vx
|
||||
predicted_state[4] = track.state[4]; // vy
|
||||
predicted_state[5] = track.state[5]; // vz
|
||||
|
||||
// 4. 转换量测到笛卡尔坐标 (z_meas)
|
||||
float z_x, z_y, z_z;
|
||||
SphericalToCartesian(meas.range, meas.azimuth, meas.elevation, z_x, z_y, z_z);
|
||||
|
||||
// 5. 计算马氏距离 (关联判据)
|
||||
float dist = CalculateMahalanobisDist(predicted_state, track.covariance_diag, z_x, z_y, z_z);
|
||||
|
||||
if (dist < GATING_THRESHOLD) {
|
||||
// 关联成功,准备 Update
|
||||
// …
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4\. 时钟跳变防护 (Sanity Check)
|
||||
|
||||
为了防止 2.6.1 中的 PTP/NTP 发生阶跃导致 $\Delta t$ 异常(例如突然跳变 100 年):
|
||||
|
||||
- **基线策略**:设置物理合理性阈值。
|
||||
- **判据**:若 `abs(dt) > 10.0f` (10 秒),视为时钟故障。
|
||||
- **动作**:
|
||||
- 不更新航迹状态。
|
||||
- 重置航迹的 `timestamp_us` 为 `meas.timestamp_us`(强制同步,但不外推状态)。
|
||||
- 触发 `SystemClockJumpEvent` 告警。
|
||||
|
||||
-----
|
||||
|
||||
## 四、总结:2.6.4 基线图谱
|
||||
|
||||
| 维度 | 核心基线 | 设计意图 |
|
||||
| :--- | :--- | :--- |
|
||||
| **对齐方向** | **Track Extrapolates to Measurement** | 尊重数据的物理生成时间,消除处理延迟对估计的影响。 |
|
||||
| **时间差计算** | **$\Delta t = t_{meas} - t_{track}$** | 基于绝对时间戳,而非处理间隔。 |
|
||||
| **乱序处理** | **Drop OOSM ($\Delta t < 0$)** | 牺牲个别数据点的利用率,换取算法的低复杂度和高吞吐。 |
|
||||
| **异常防护** | **Sanity Check (\> 10s)** | 防止时钟源故障导致航迹“飞”出地球。 |
|
||||
|
||||
-----
|
||||
@@ -0,0 +1,134 @@
|
||||
---
|
||||
tags: []
|
||||
date created: 星期三, 十一月 26日 2025, 10:55:22 晚上
|
||||
date modified: 星期三, 十一月 26日 2025, 11:02:47 晚上
|
||||
---
|
||||
|
||||
# 2.6.5 全链路延迟审计与抖动监控 (End-to-End Latency Auditing & Jitter Monitoring)
|
||||
|
||||
如果说 2.6.4 是为了让算法“算得对”,那么 2.6.5 就是为了证明系统“跑得快”且“跑得稳”。这是系统性能的**心电图**,也是触发 **2.3.5 热节流** 和 **2.3.4 故障恢复** 的核心依据。
|
||||
|
||||
-----
|
||||
|
||||
## TL;DR
|
||||
|
||||
本节确立了 **“关键节点埋点 (Checkpointing) + 驻留时间计算 (Residence Time)”** 的基线策略。
|
||||
利用数据包中携带的 **不可变时间戳 (Birth Timestamp)** 作为 T0,在流水线的每个交接点(Handoff Point)采集当前时间,计算 **阶段耗时** 与 **全系统驻留时间**。监控数据通过 **无锁直方图 (Lock-free Histogram)** 聚合,并实时计算 P99 延迟与抖动(Jitter),一旦超出 CPI 周期阈值,立即触发流控。
|
||||
|
||||
-----
|
||||
|
||||
## 一、 约束输入与对齐 (Constraints & Alignment)
|
||||
|
||||
基于前序基线,我们面临以下硬性约束:
|
||||
|
||||
1. **时间基准**:所有打点必须使用 **2.6.1** 确立的 `HighPrecisionClock` (TSC-based),以保证纳秒级精度和极低开销(\< 20ns)。
|
||||
2. **零干扰**:监控逻辑严禁阻塞业务线程。严禁在热路径上进行文件 I/O(写日志)或复杂的锁操作。
|
||||
3. **关联性**:必须能够将延迟数据关联到具体的 `StationID` 和 `TraceID`,以便定位是哪个雷达阵面或哪一帧数据导致了卡顿。
|
||||
|
||||
-----
|
||||
|
||||
## 二、 权衡分析与选项呈现 (Trade-off Matrix)
|
||||
|
||||
### 议题 1:埋点粒度 (Granularity)
|
||||
|
||||
| 选项 | A. 仅首尾打点 (Black Box) | B. 细粒度逐级打点 (White Box) **(推荐)** |
|
||||
| :--- | :--- | :--- |
|
||||
| **机制** | 仅在 `DataReceiver` 入口和 `DisplayController` 出口记录。计算 $T_{out} - T_{in}$。 | 在每个模块的 Input/Output 队列处均打点:Rx, DSP\_Start, DSP\_End, Track, Tx… |
|
||||
| **开销** | 极低。 | 低(TSC 读取极快)。 |
|
||||
| **诊断能力** | **差**。只能知道系统慢了,不知道是 GPU 算慢了,还是 PCIe 堵了,还是调度器卡了。 | **强**。能精确绘制“火焰图”,定位瓶颈环节。 |
|
||||
| **结论** | 仅适用于最终用户 SLA。 | **研发与运维的标准解**。 |
|
||||
|
||||
### 议题 2:数据聚合策略 (Aggregation Strategy)
|
||||
|
||||
| 选项 | A. 全量日志 (Raw Logs) | B. 内存直方图聚合 (In-Memory Histogram) **(推荐)** |
|
||||
| :--- | :--- | :--- |
|
||||
| **机制** | `LOG(INFO) << "Packet " << id << " took " << lat << "us";` | 维护一组原子计数器桶(Buckets),如 `<1ms`, `1-5ms`… 仅统计次数。 |
|
||||
| **IO 压力** | **极大**。每秒 10k 包产生 10k 条日志,瞬间打爆磁盘 IOPS。 | **零**。仅涉及内存原子自增 (`fetch_add`)。 |
|
||||
| **实时性** | 延迟高(需等日志落盘分析)。 | **实时**。控制面可随时读取当前 P99 值。 |
|
||||
|
||||
-----
|
||||
|
||||
## 三、 基线确立与实施规范
|
||||
|
||||
为了实现“显微镜级”的性能观测,我们确立 **B. 细粒度逐级打点** + **B. 内存直方图聚合** 为基线。
|
||||
|
||||
### 1\. 关键路径检查点定义 (Checkpoint Definition)
|
||||
|
||||
我们将数据包在系统中的生命周期划分为 5 个关键时刻(Timestamp):
|
||||
|
||||
- **T0 (Birth/Ingress)**: `DataReceiver` 收到 UDP 包的时刻(硬件/内核打点,见 2.6.2)。
|
||||
- *阶段 1:接收耗时 (Rx Latency)* = $T_1 - T_0$
|
||||
- **T1 (Dispatch)**: `AssemblyBuffer` 组装完成,推入 GPU 输入队列的时刻。
|
||||
- *阶段 2:排队与传输 (Queue & PCIe)* = $T_2 - T_1$
|
||||
- **T2 (Algo Start)**: `SignalProcessor` 从队列取出数据,开始 CUDA Kernel 的时刻。
|
||||
- *阶段 3:计算耗时 (Compute)* = $T_3 - T_2$
|
||||
- **T3 (Algo End)**: 信号处理完成,生成点迹/航迹的时刻。
|
||||
- *阶段 4:后处理与关联 (Post-Proc)* = $T_4 - T_3$
|
||||
- **T4 (Egress)**: `DisplayController` 完成序列化并调用 `sendto` 的时刻。
|
||||
|
||||
**全链路驻留时间 (Residence Time)** = $T_4 - T_0$。
|
||||
|
||||
### 2\. 数据结构:伴随式遥测对象 (`TelemetryContext`)
|
||||
|
||||
为了避免在 `DataPacket` 中增加过多字段(膨胀 Payload),我们采用 **“边车模式 (Sidecar)”** 或利用 `TraceContext`(如果支持携带额外数据)。考虑到 C++ 性能,建议直接在 `DataPacket::Header` 中扩展调试字段(仅在 Debug/Profile 模式下启用)或使用 **Thread Local 统计器**。
|
||||
|
||||
**生产环境基线(高性能方案)**:
|
||||
不随包携带所有中间时间戳,而是 **即时聚合**。
|
||||
|
||||
```cpp
|
||||
// 伪代码:各模块内的埋点逻辑
|
||||
void SignalProcessor::onData(DataPacket& pkt) {
|
||||
uint64_t now = Clock::now();
|
||||
|
||||
// 1. 计算上一阶段耗时 (排队延迟)
|
||||
// Packet Header 中记录了上一个节点的离开时间 last_leav_time
|
||||
uint64_t queue_latency = now - pkt.header.last_leave_time;
|
||||
Metrics::Histogram("dsp_queue_latency")->observe(queue_latency);
|
||||
|
||||
// 2. 执行业务
|
||||
process(pkt);
|
||||
|
||||
// 3. 计算本阶段耗时
|
||||
uint64_t done = Clock::now();
|
||||
uint64_t compute_latency = done - now;
|
||||
Metrics::Histogram("dsp_compute_latency")->observe(compute_latency);
|
||||
|
||||
// 4. 更新 Header,传给下游
|
||||
pkt.header.last_leave_time = done;
|
||||
}
|
||||
```
|
||||
|
||||
### 3\. 抖动监控与告警阈值 (Jitter Monitor)
|
||||
|
||||
单纯看平均耗时(Avg)会掩盖问题,我们必须监控 **P99 (99 分位)** 和 **抖动 (Jitter)**。
|
||||
|
||||
- **抖动定义**:$J_i = |(T4_i - T4_{i-1}) - (T0_i - T0_{i-1})|$
|
||||
- 即:*输出间隔的变化量* 与 *输入间隔的变化量* 之差。
|
||||
- 理想情况下,如果系统处理能力恒定,输入是 10ms 间隔,输出也应该是 10ms 间隔,抖动为 0。
|
||||
- **阈值设定**:
|
||||
- **Warning**: P99 Latency \> $0.8 \times \text{CPI\_Interval}$。
|
||||
- **Critical**: P99 Latency \> $1.0 \times \text{CPI\_Interval}$(系统已无法实时处理,必然积压)。
|
||||
|
||||
### 4\. 闭环反馈:触发热节流 (2.3.5 Linkage)
|
||||
|
||||
这是 2.6.5 与 2.3.5 的联动点。热节流不仅仅由**温度**触发,也应由**性能拥塞**触发。
|
||||
|
||||
- **逻辑**:
|
||||
`MonitoringModule` 每秒轮询一次延迟指标。
|
||||
- 如果 `dsp_queue_latency` (排队延迟) 持续增长 -\> 说明 GPU 处理不过来。
|
||||
- **动作**:发布 `SystemOverloadEvent(Type=COMPUTE_LAG)`。
|
||||
- **响应**:调度器下发 `SetComputeThrottleEvent(Level=1)`,通过主动降级(如减少点迹提取数量)来恢复实时性。
|
||||
|
||||
-----
|
||||
|
||||
## 四、 总结:2.6 章节整体回顾
|
||||
|
||||
至此,**2.6 时序同步与数据一致性** 已全部完成。我们构建了一套严密的时空治理体系:
|
||||
|
||||
1. **2.6.1 时钟源**:Hardware PTP + TSC,确保尺子是准的。
|
||||
2. **2.6.2 打点**:Kernel/Hardware Ingress Timestamp,确保起点是真实的。
|
||||
3. **2.6.3 对齐**:原地乱序重组,确保数据在进入算法前是齐整的。
|
||||
4. **2.6.4 融合**:异步外推,确保航迹与量测在物理时间上是对齐的。
|
||||
5. **2.6.5 审计**:全链路耗时监控,确保系统没有因过载而失速。
|
||||
|
||||
-----
|
||||
Reference in New Issue
Block a user