Files
Inbox/系统基座文件/2/2.4/2.4.4 热节流响应与流量整形 (Thermal Throttling Response & Traffic Shaping).md
2025-12-11 07:24:36 +08:00

122 lines
6.2 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.

---
tags: []
aliases:
- 2.4.4 热节流响应与流量整形 (Thermal Throttling Response & Traffic Shaping)
date created: 星期一, 十一月 24日 2025, 4:33:19 下午
date modified: 星期一, 十一月 24日 2025, 4:38:23 下午
---
# 2.4.4 热节流响应与流量整形 (Thermal Throttling Response & Traffic Shaping)
这是数据网关的“被动防御机制”。不同于 2.3.5 中 `SignalProcessor` 的**主动降速**(通过 `sleep` 减少计算热量),`DisplayController` 在此处的任务是通过**减少数据发送量**和**降低发送频率**,来降低 CPU 的序列化开销、PCIe 总线功耗以及网卡的中断频率,从而辅助系统整体降温。
## 一、 约束输入与对齐 (Constraints & Alignment)
基于 ECN-2025-001 和之前的讨论,我们需对齐以下硬性约束:
1. **被动执行**`DisplayController` 不感知温度,只响应 `SetComputeThrottleEvent` 指令。
2. **原子性保持**:即使在节流状态下,发送出去的 `TrackDataBatch` 仍然必须是**原子批次**。严禁将一个 CPI 的数据拆成两半发送(例如发一半航迹),这会破坏显控端的一致性。
3. **优先级明确**
- **P0 (保命)**:确认航迹 (Confirmed Tracks)。这是雷达存在的意义。
- **P1 (辅助)**:未确认航迹 (Tentative)、系统状态。
- **P2 (冗余)**:点迹 (Plots)、调试日志、原始回波切片。
---
## 二、 权衡分析与选项呈现 (Trade-off Matrix)
### 议题:流量整形策略 (Shaping Strategy)
|**选项**|**A. 仅内容剪裁 (Content Pruning)**|**B. 仅频率抽稀 (Frame Skipping)**|**C. 混合降级 (Hybrid Degradation) (推荐)**|
|---|---|---|---|
|**机制**|保持 100Hz 发送频率,但把包里的点迹删掉,包变小了。|保持包内容完整,但每隔一帧发一帧(降为 50Hz。|**轻度过热**时剪裁内容;**重度过热**时既剪裁内容又抽稀频率。|
|**热收益**|**中**。减少了序列化开销和带宽,但网卡中断频率没变(依然是 100Hz。|**高**。网卡中断减半,序列化开销减半。|**极高**。全方位降低负载。|
|**显控体验**|**流畅但空洞**。画面依然丝滑,只是点迹没了。|**卡顿但丰富**。画面有顿挫感,但信息量全。|**平滑过渡**。优先保流畅,实在不行再保生存。|
---
## 三、 基线确立与实施规范
为了在“保护硬件”和“维持态势感知”之间取得最佳平衡,我们确立 **C. 混合降级** 为基线。
### 1. 节流等级映射表 (Throttling Mapping Table)
我们定义各级节流状态下,`DisplayController` 的具体行为规范:
|**节流等级 (Throttle Level)**|**发送频率 (Frequency)**|**内容策略 (Content Policy)**|**显控端表现**|
|---|---|---|---|
|**L0 (NO_THROTTLE)**|**100% (全速)**|**全量** (航迹 + 点迹 + 状态 + 调试)|正常显示。|
|**L1 (LIGHT)**|**100% (全速)**|**剪裁 P2** (丢弃点迹、调试信息)。保留所有航迹。|画面流畅,但背景点迹消失。提示 "Data Pruned"。|
|**L2 (HEAVY)**|**50% (二抽一)**|**剪裁 P1+P2** (仅保留**确认航迹**)。|画面帧率减半 (50Hz),仅显示核心目标。提示 "Low Rate"。|
|**L3 (SUSPEND)**|**0% (暂停)**|**停止发送** (仅发心跳包维持连接)。|画面静止/黑屏。提示 "Server Overheat"。|
### 2. 实现规范:发送间隔插入 (Gap Insertion)
为了实现 L2 级别的降频,我们不能依赖上游 `SignalProcessor` 的降速(虽然它也在降,但我们要在网络层做双重保险)。
- **位置**`DisplayController` 的独立 IO 线程循环中。
- **逻辑**:维护一个 `frame_counter`
- **代码范式**
```cpp
void DisplayController::ioLoop() {
uint64_t frame_counter = 0;
while (running_) {
// 1. 从队列取数据
TrackDataPacket packet;
if (!queue_.pop(packet)) continue; // Non-blocking pop or wait
// 2. 获取当前节流等级 (原子读取,无锁)
auto level = current_throttle_level_.load(std::memory_order_relaxed);
// 3. L3 级熔断:直接丢弃,仅维持心跳
if (level == Level::SUSPEND) {
sendHeartbeat();
continue;
}
// 4. L2 级抽稀Gap Insertion (每2帧丢1帧)
frame_counter++;
if (level == Level::HEAVY && (frame_counter % 2 != 0)) {
continue; // Drop this frame completely
}
// 5. L1/L2 级内容剪裁 (在序列化前执行节省CPU)
if (level >= Level::LIGHT) {
packet.plots.clear(); // 丢弃点迹
packet.debug_info.clear();
}
if (level >= Level::HEAVY) {
// 仅保留确认航迹
packet.tracks.erase(
std::remove_if(packet.tracks.begin(), packet.tracks.end(),
[](const Track& t){ return t.status != CONFIRMED; }),
packet.tracks.end());
}
// 6. 序列化并发送 (Protobuf Encode -> sendto)
serializeAndSend(packet);
}
}
```
### 3. 流量整形对丢包检测的影响 (2.4.3 联动)
- **问题**:如果在 L2 级别主动抽稀(丢弃偶数帧),显控端会不会误判为“丢包”?
- **解决方案**
- **序列号连续性**`batch_sequence_id` 是在**序列化步骤(第 6 步)**生成的。
- **结论**:被主动丢弃的帧(第 4 步)根本不会获得序列号。因此,发送出去的数据包序列号**依然是连续的**。显控端不会误报丢包,只会感知到数据刷新变慢(两次更新的时间间隔变大)。这是非常优雅的设计。
---
## 总结2.4.4 基线图谱
|**策略维度**|**核心基线**|**设计意图**|
|---|---|---|
|**响应模式**|**被动执行**|听从 `ResourceCoordinator` 指挥,不独立决策。|
|**L1 策略**|**内容剪裁 (Pruning)**|牺牲次要数据,保流畅度,降序列化开销。|
|**L2 策略**|**频率抽稀 (Skipping)**|牺牲刷新率,保核心数据,降中断和总线功耗。|
|**序列号**|**后置生成**|确保主动丢弃不破坏传输层的序列连续性。|