跳到主要内容

G5 通信评估观测与结果存储设计规格

版本:1.0.0 状态:Draft 创建日期:2026-04-28 最后更新:2026-04-28 作者:xiang.li 前置互联通信G5仿真建模设计规格

变更历史

版本日期变更说明
1.0.12026-04-28修正 stats key 前缀、per-chip 聚合数据来源、ThreadUnblocked 插入点遗漏、LinkIdle 实现方案细化、补充文件生命周期和 API schema
1.0.02026-04-28初版:事件追踪框架、结果结构化、数据库 schema、文件存储方案

@tbl-spec-obs-01 文档变更历史


Summary

为 G5 通信原语仿真增加观测基础设施(instrumentation)和结构化结果存储。G5 内部已建模 link 竞争、buffer 占用、credit 流控等硬件行为,但这些中间状态在仿真结束后全部丢失,只输出一个总延迟数字。本 spec 定义三件事:(1) Rust 仿真器内的事件追踪框架,在关键状态变化时记录 trace record;(2) Python 适配层的结构化结果,保留 per-chip 分解和 stats 全量数据;(3) 数据库和文件存储方案,支持跨实验对比查询和未来的波形可视化。

Motivation

现状与问题

数据丢失链:G5 仿真器内部有完整的组件级状态(PhyLink busy 状态、CDMA outstanding 计数、thread 阻塞状态、per-hop 传输时间),但经过三层转换后只剩一个数字:

  1. Rust 仿真器产出 SimRecord[](per-指令)+ stats_dict(聚合计数器)+ 内部事件(C2CLinkDone/AckArrived 等 19 种),但内部事件从未导出
  2. G5ResultAdapter 将 SimRecord 按 source_op_id 聚合为 per-op 的 t_compute/t_comm/t_wait,原始 record 丢弃
  3. engine_adapter._run_comm_primitive_evaluation()EngineResult只提取 aggregates.total_time,计算一个 bus_bw_gb_per_s,其余全部丢弃
  4. 数据库的 EvaluationResult 表为 LLM 推理设计(dp/tp/pp/ep/tps/mfu),comm primitive 结果用 dp=N, tp=1, tps=0, mfu=0 占位

后果

  • 无法对比不同拓扑/算法的延迟分布,只能逐个看总延迟
  • 无法识别瓶颈在哪一层(link 竞争?credit 阻塞?switch 排队?)
  • 无法分析 straggler chip(哪个芯片最慢、为什么慢)
  • 无法做 CrossRing 级别的波形可视化(link 利用率曲线、buffer 占用曲线等)

驱动力

项目需要对比不同拓扑 x 原语 x 算法的通信性能。参数扫描功能已能生成多种配置组合并提交 G5 仿真,但仿真结果太粗,无法做有意义的对比分析。

Terminology

名词定义
TraceRecord本 spec 定义的事件追踪记录,记录仿真过程中组件状态变化的时刻和数值
SimRecordG5 已有的指令执行记录(engine/cmd_id/start_ns/end_ns),记录一条指令的完整执行区间
StatsG5 已有的聚合计数器框架(HashMap<String, f64>),只存总量不存时间序列
CommSimResult本 spec 定义的通信仿真结构化结果,包含 summary + per_chip + stats + trace 引用

@tbl-spec-obs-02 Terminology

Goals / Non-Goals

Goals

  • G1: Rust 仿真器在关键状态变化时记录 TraceRecord,覆盖 link 利用率、CDMA outstanding、thread 阻塞、per-hop 延迟四类事件
  • G2: Python 适配层输出结构化 CommSimResult,包含 per-chip 延迟分解和 straggler 分析
  • G3:新建 comm_eval_results 数据库表,支持按 primitive/algorithm/topology/msg_size 做 SQL 查询
  • G4: TraceRecord 以 Parquet 文件存储,支持按时间范围分页读取
  • G5:现有 stats 全量计数器完整保留到数据库,不再丢弃

Non-Goals

  • 前端对比图表和波形可视化 UI(属于独立 spec)
  • Math 模型(Alpha-Beta/LogP/LogGP/LoGPC)的结果增强
  • 修改 G5 仿真器的仿真精度或物理建模
  • 实时流式输出 trace(仿真完成后一次性导出)

Background / Prior Art

业界仿真器观测方案对比

维度BookSim 2gem5 StatsNS-3 TracingCrossRing
记录机制周期采样(每 N cycle)事件驱动 + 周期 dump回调式事件源/汇逐周期采样 + 事件日志
时序数据每采样周期一个聚合值周期 dump/reset 产出趋势每事件一条带时间戳记录逐 flit 管线时间戳 + 逐周期 buffer 深度
输出格式stdout 文本stats.txt / JSONPCAP + ASCII traceCSV + Parquet + SQLite
开销控制只在采样间隔收集收集连续但导出按需未连接 sink 时零开销全量采集,Parquet 压缩存储

@tbl-spec-obs-03 业界仿真器观测方案对比:维度,BookSim 2

参考链接

本项目选择:事件驱动日志

G5 本身是事件驱动仿真器(BinaryHeap 优先队列),在事件处理函数中追加一条 TraceRecord 是最自然的插入方式。相比周期采样:

  • 数据量更小(只记录状态变化点,不记录无变化的周期)
  • 时间精度更高(精确到事件发生的 ns,不受采样间隔限制)
  • 对仿真性能影响更小(只在事件处理时追加一次 Vec push)
  • 前端可通过插值重建连续波形(CrossRing 的 FIFO 波形本质上也是阶梯插值)

Guide-Level Explanation

场景:对比 Fat-tree vs Torus 上 Ring AllReduce 的延迟

假设功能已实现,用户工作流:

1. 提交仿真

在 CommunicationEval 页面,用户配置两组参数扫描:

  • 拓扑:Fat-tree-k4, Torus-2D-4x4
  • 原语:AllReduce,算法:Ring
  • 消息大小:1KB, 64KB, 1MB, 64MB, 1GB

点击"开始评估",系统提交 10 个 G5 仿真任务(2 拓扑 x 5 消息大小)。

2. 仿真过程中的数据采集

每个仿真任务运行时,Rust 仿真器在以下时刻记录 TraceRecord:

  • PhyLink 开始/结束传输 -> link_busy / link_idle 事件
  • CDMA outstanding 变化 -> ostd_change 事件
  • CDMA thread 被 credit/fence 阻塞/解除 -> thread_blocked / thread_unblocked 事件
  • 数据包到达每一跳 -> hop_arrive 事件

仿真完成后,Python 侧收到:

  • SimRecord[](CDMA 指令级,已有)
  • stats_dict(聚合计数器,已有)
  • TraceRecord[](时序事件,新增

3. 结果存储

adapter 将结果组装为 CommSimResult

{
"summary": {
"total_latency_ns": 4523.7,
"total_comm_bytes": 15728640,
"num_participants": 16,
"algorithm_steps": 30, # Ring AllReduce: 2*(N-1)
},
"per_chip": [
{"chip_id": 0, "latency_ns": 4523.7, "cdma_blocked_ns": 120.3, "is_straggler": True},
{"chip_id": 1, "latency_ns": 4401.2, "cdma_blocked_ns": 15.0, "is_straggler": False},
...
],
"straggler": {
"chip_id": 0,
"ratio": 1.028, # straggler_latency / median_latency
"blocked_ns": 120.3,
},
"stats": { ... }, # G5 stats_dict 全量
}

聚合指标写入 comm_eval_results 表(支持 SQL 查询),TraceRecord 写入 Parquet 文件(支持波形可视化)。

4. 对比查询

前端从数据库查询同一实验下的所有结果,按 topology_name 分组,画延迟-消息大小曲线。点击某个数据点可展开看 per-chip 延迟分布和 straggler 分析。未来可进一步加载 Parquet trace 文件画 link 利用率波形。


Detailed Design

概念模型

观测系统分三层,每层独立可用,不相互依赖:

层级数据类型粒度存储位置用途
L1 聚合指标CommSimResult.summary + per_chipper-chipDB comm_eval_resultsSQL 查询、对比表格、延迟曲线
L2 全量计数器stats_dictper-component 总量DB comm_eval_results.stats JSON 列深入分析单次仿真的资源使用
L3 时序事件TraceRecord[]per-event (ns 精度)Parquet 文件波形可视化、时间线分析

@tbl-spec-obs-04 概念模型:层级,数据类型

设计原理:L1 分两部分——summary 级聚合只需改 Python(停止丢弃已有数据),per-chip 聚合需要 Rust 侧配合新增少量 stats key。L2 只需改 Python。L3 需要 Rust 代码新增 instrumentation,是主要工作量。三层可分阶段实现,L1+L2 先行可用于对比分析,L3 为未来波形可视化做准备。

L1:结构化聚合结果

设计原理:当前 _run_comm_primitive_evaluation() 在拿到完整的 EngineResult 后只提取一个 total_time,这是最大的数据浪费点。修复方式是保留 EngineResult 中已有的全部信息,并增加 per-chip 维度的聚合。

CommSimResult 概念模型

CommSimResult
├── summary # 全局聚合:总延迟、通信量、步数
├── per_chip[] # 每 chip 的延迟和阻塞分析
├── straggler # 最慢 chip 的识别和原因
├── stats # G5 stats_dict 全量(L2)
└── trace_file_path # Parquet 文件路径(L3,可选)

per-chip 聚合的数据来源:通信原语仿真时,CDMA Transfer/Send 不产生 SimRecord(comm_primitive_pipeline.py 已确认),因此无法从 SimRecord 做 per-chip 分组。现有 stats 中 cdma_chip{i}_unit{j}.* 的计数器只有总量(cmd_count, total_bytes, blocked_count),没有时间区间信息。

为支持 per-chip 延迟聚合,需要在 Rust 侧新增 per-chip 时间戳 stats key

新增 stats key含义插入点
cdma_chip{i}.first_cmd_ns该 chip 首条 CDMA 命令的仲裁时刻cdma.rs try_arbitrate 首次成功时
cdma_chip{i}.last_done_ns该 chip 最后一条 CDMA 命令完成时刻cdma.rs on_remote_done / on_receive_done

@tbl-spec-obs-05 L1:结构化聚合结果:新增 stats key,含义

这属于 Rust 侧小改动(在已有的 stats 框架中新增 2 个 key/chip),不涉及仿真逻辑变更。

per-chip 延迟定义:

$$\begin{equation} T_{\text{chip}_i} = \text{cdma\_chip}\{i\}\text{.last\_done\_ns} - \min_{j}(\text{cdma\_chip}\{j\}\text{.first\_cmd\_ns}) \label{eq:obs-per-chip-latency} \end{equation}$$

straggler 识别

$$\begin{equation} R_{\text{straggler}} = \frac{T_{\text{max\_chip}}}{\text{median}(T_{\text{all\_chips}})} \label{eq:obs-straggler-ratio} \end{equation}$$

其中 $T_{\text{max\_chip}}$ 为最慢 chip 的延迟,$\text{median}(T_{\text{all\_chips}})$ 为所有 chip 延迟的中位数。$R_{\text{straggler}} > 1.1$ 时标记为 straggler。

L2: Stats 全量保留

设计原理:G5 的 stats 框架已经收集了丰富的 per-component 计数器(见下表),当前通过 trace_meta["stats"] 传递但在 engine_adapter.py 被丢弃。修复方式:直接将 stats dict 序列化为 JSON 存入数据库。

已有的 stats key(无需 Rust 改动)

完整 key 示例含义
cdma_chip{i}_unit{j}.cmd_countCDMA 单元执行的指令数
cdma_chip{i}_unit{j}.total_bytesCDMA 单元传输的总字节数
cdma_chip{i}_unit{j}.blocked_countoutstanding buffer 满导致的阻塞次数
multi_chip.core_subsys.tiu.total_flopsTIU 浮点运算总量
multi_chip.core_subsys.sdma.total_bytes片内 SDMA 传输字节数
multi_chip.bus.total_transfersNoC 总传输次数
multi_chip.kernel.total_events仿真处理的事件总数
multi_chip.kernel.total_sim_time_ns仿真总时间 (ns)

@tbl-spec-obs-06 L2: Stats 全量保留:完整 key 示例,含义

注:multi-chip 仿真的 stats 根 prefix 为 multi_chip(见 multi_chip.rsStats::new("multi_chip")),CDMA 单元的 prefix 为 cdma_chip{i}_unit{j}(独立于根 prefix,见 cdma.rs 构造函数)。

L3:事件追踪框架

设计原理:G5 是事件驱动仿真器,所有状态变化都发生在事件处理函数中。在这些函数中追加一条 TraceRecord 到 Vec 是侵入性最小的方案——不改变仿真逻辑,不影响事件调度,只是"旁路记录"。

TraceRecord 概念

每条 TraceRecord 表示一个状态变化点:某个组件在某个时刻从一个状态转移到另一个状态,或者某个数值发生了变化。

struct TraceRecord {
time_ns: f64,
category: TraceCategory,
component: String,
value: f64,
detail: Option<TraceDetail>,
}
  • time_ns:事件发生的仿真时间
  • category:事件类别(枚举,见下方)
  • component:产生事件的组件标识(如 "link_c0_sw0", "cdma_chip2_unit0"
  • value:状态值(利用率、占用数、延迟值等,含义由 category 决定)
  • detail:可选的附加信息(包 ID、源/目标 chip 等)

事件类别

Category触发时机component 格式value 含义插入点
LinkBusyPhyLink.transmit() / transmit_rsp() 被调用link_{from}_{to}_{vc}本次传输的串行化耗时 (ns)。vc = reqrspc2c_network.rs PhyLink::transmit / transmit_rsp
LinkIdleLinkIdleAt 定时事件触发(见下方实现方案)link_{from}_{to}_{vc}0.0 (idle)multi_chip.rs 处理 LinkIdleAt 事件
OstdChangeCDMA outstanding_count 变化cdma_chip{i}_unit{j}变化后的 outstanding_countcdma.rs try_arbitrate / on_remote_done
ThreadBlockedCDMA thread 进入 TCreditWait 或 FenceWaitcdma_chip{i}_unit{j}_t{k}0.0 (blocked)cdma.rs try_arbitrate
ThreadUnblockedCDMA thread 从阻塞状态恢复为 Readycdma_chip{i}_unit{j}_t{k}1.0 (unblocked)cdma.rs notify_tcredit / on_fence_done / notify_write_done
HopArriveC2CLinkDone 事件处理时flow_{src}_{dst}本跳延迟 (ns)multi_chip.rs handle C2CLinkDone

@tbl-spec-obs-07 事件类别:Category,触发时机

LinkBusy/LinkIdle 同时追踪 REQ VC 和 RSP VC。PhyLink 内部有两个独立的串行化队列(busy_until_ns 用于数据包,busy_until_ns_rsp 用于 ACK/NAK),ACK 密集场景下 RSP VC 竞争可能成为瓶颈,需要独立观测。

ThreadUnblocked 的三个触发路径

  • notify_tcredit:远端 tcredit 到达,从 TCreditWait 恢复
  • on_fence_done:fence 依赖的所有 pending 操作完成,从 FenceWait 恢复
  • notify_write_done:远端 write_done 通知到达,pending_count 归零后从 FenceWait 恢复

LinkIdle 实现方案

PhyLink 没有原生的 idle 回调机制。采用定时事件方案

  1. PhyLink::transmit() / transmit_rsp() 记录 LinkBusy TraceRecord 时,同时向事件队列调度一个 LinkIdleAt 定时事件,时间为当前 busy_until_ns(或 busy_until_ns_rsp
  2. 需要在 Event 枚举中新增 LinkIdleAt { link_key: String, vc: String } 变体
  3. LinkIdleAt 事件触发时,检查对应 link 的 busy_until 是否确实 <= 当前时间(可能被后续 transmit 延长):
    • 如果确实空闲 -> 记录 LinkIdle TraceRecord
    • 如果被延长 -> 忽略该事件(后续 transmit 会调度新的 LinkIdleAt)
  4. 仅在 trace_enabled 时调度 LinkIdleAt 事件,关闭追踪时零开销

追踪开关

TraceRecord 采集默认关闭,通过配置启用:

CommPrimitiveSpec(
...
trace_enabled=True, # 启用追踪
trace_categories=None, # None = 全部类别;或指定子集如 ["link", "ostd"]
)

Rust 侧通过 MultiChipProgram 传入 trace_config: Option<TraceConfig>,仿真器据此决定是否记录。关闭时零开销(不分配 Vec,不执行记录逻辑)。

数据量估算

以 32 芯片 Ring AllReduce 1MB 消息为例:

  • Link 事件:每步 ~32 条 busy + 32 条 idle,共 2*31 步 ≈ 4000 条
  • CDMA outstanding:每步 ~32 变化 x 2 (inc/dec) ≈ 4000 条
  • Thread blocked:取决于竞争程度,估计 ~500 条
  • Hop arrive:每包每跳一条,32 芯片 x 平均 2 跳 x 62 步 ≈ 4000 条

总计约 12000 条 TraceRecord,每条约 100 字节,原始大小 ~1.2 MB。Parquet 压缩后估计 ~200 KB。

数据库 Schema

comm_eval_results

与现有 evaluation_results 表独立,通过 experiment_id 关联到同一个 experiments 表。

类型用途
idINTEGER PK主键
experiment_idINTEGER FK关联实验
task_idVARCHAR(36)任务 UUID
config_snapshotJSON完整配置快照(可复现)
输入参数(indexed)
primitiveVARCHAR(20)allreduce/allgather/reducescatter/alltoall/p2p
algorithmVARCHAR(30)ring/halving_doubling/tree/bruck/pairwise/auto
msg_size_bytesINTEGER消息大小
num_participantsINTEGER参与芯片数
topology_nameVARCHAR(255)拓扑预设名称
dtypeVARCHAR(10)数据类型
输出指标(indexed)
total_latency_nsFLOAT总延迟 (ns)
bus_bw_gb_per_sFLOAT等效总线带宽 (GB/s)
max_chip_latency_nsFLOAT最慢 chip 延迟 (ns)
straggler_ratioFLOATstraggler 比率(公式 $\eqref{eq:obs-straggler-ratio}$
total_comm_bytesINTEGER总通信字节数
algorithm_stepsINTEGER算法步数
详细数据
per_chip_summaryJSONper-chip 延迟和阻塞分析
statsJSONG5 stats_dict 全量
trace_file_pathVARCHAR(512)Parquet trace 文件路径(可选,L3)
created_atDATETIME创建时间

@tbl-spec-obs-08 comm_eval_results 表:列,类型

索引(experiment_id), (primitive, algorithm), (topology_name), (msg_size_bytes)

设计原理:输入参数作为独立列而非嵌入 JSON,是为了支持 WHERE primitive='allreduce' AND topology_name LIKE 'fat-tree%' ORDER BY msg_size_bytes 这类对比查询。LLM 评估的 evaluation_results 表不变,两类结果通过不同表自然分离。

文件存储

data/traces/
├── {experiment_id}/
│ ├── {result_id}_trace.parquet # TraceRecord 事件日志
│ └── {result_id}_records.parquet # SimRecord 原始数据(可选)

Parquet schema

TraceRecord:

  • time_ns: DOUBLE
  • category: STRING (枚举值)
  • component: STRING
  • value: DOUBLE
  • detail_json: STRING (可选,JSON 序列化的附加信息)

选择 Parquet 而非 CSV:列式存储压缩率高(重复的 category/component 值压缩效果好),支持按 time_ns 范围的谓词下推(前端分页加载波形时只读取时间窗口内的数据)。

文件生命周期管理:trace 文件随对应的 comm_eval_results 记录删除而级联清理。在应用层 delete_comm_result() 中,先删除 trace_file_path 指向的文件,再删除 DB 记录。实验级批量删除(delete_experiment())时遍历关联结果逐一清理文件。

集成点

上游(Rust 仿真器)

  • TraceCollector 作为新结构体注入 MultiChipSimulator,与现有 Stats 并列
  • 通过 PyO3 FFI 将 Vec<TraceRecord> 导出为 Python list of dict
  • 不改变现有 SimRecordStats 的行为

中游(Python 适配层)

  • G5ResultAdapter.convert() 增加 per-chip 聚合逻辑
  • engine_adapter._run_comm_primitive_evaluation() 构建 CommSimResult 替代当前的 5 字段 plan
  • 新增 TraceWriter 将 TraceRecord 写入 Parquet

下游(数据库 + API)

  • _save_task_result_to_db()comm_primitive workload 走独立的保存路径,写入 comm_eval_results
  • API 新增端点,支持按条件查询和排序(schema 见下方)
  • 现有 experiments 表和 WebSocket 推送不变

API 端点 schema

GET /evaluation/comm-results

查询参数:

参数类型必填说明
experiment_idint按实验 ID 过滤
primitivestring按通信原语过滤
algorithmstring按算法过滤
topology_namestring按拓扑名过滤(支持 LIKE 模糊匹配)
sort_bystring排序字段(默认 created_at,可选 total_latency_ns/msg_size_bytes/bus_bw_gb_per_s
sort_orderstringascdesc(默认 desc
pageint页码(默认 1)
page_sizeint每页条数(默认 50)

@tbl-spec-obs-09 API 端点 schema:参数,类型

返回 schema:

{
"results": [
{
"id": 1,
"experiment_id": 10,
"task_id": "uuid",
"primitive": "allreduce",
"algorithm": "ring",
"msg_size_bytes": 1048576,
"num_participants": 32,
"topology_name": "fat-tree-k4",
"dtype": "bf16",
"total_latency_ns": 4523.7,
"bus_bw_gb_per_s": 221.3,
"max_chip_latency_ns": 4523.7,
"straggler_ratio": 1.028,
"total_comm_bytes": 15728640,
"algorithm_steps": 62,
"per_chip_summary": [...],
"has_trace": true,
"created_at": "2026-04-28T10:30:00"
}
],
"total": 100,
"page": 1,
"page_size": 50
}

注:statsconfig_snapshot 因体积较大不在列表接口返回,通过 GET /evaluation/comm-results/{id} 单条详情接口获取。has_tracetrace_file_path IS NOT NULL 推导。

Alternatives Considered

维度方案 A:事件日志 (选定)方案 B:周期采样方案 C:扩展现有 Stats
时间精度ns 级(事件发生时刻)取决于采样间隔无时间维度(只有总量)
数据量只记录状态变化,~12K 条/次每周期每组件一条,可达数百万条不增加额外数据
实现复杂度中(新增 TraceCollector + 插入点)低(周期回调统一采集)低(新增 stats key)
仿真性能影响极小(Vec push)可能显著(高频采样)
波形可视化能力完整(阶梯插值重建连续波形)完整(原生时间序列)无法支持
对比查询能力通过 L1 聚合指标通过 L1 聚合指标通过扩展 stats key

@tbl-spec-obs-10 Alternatives Considered

选择理由:方案 A 在数据量和精度之间取得最佳平衡。G5 本身是事件驱动仿真器,事件日志是最自然的观测方式。方案 B 的数据量在大规模仿真时可能失控。方案 C 无法支持波形可视化这一关键的未来需求。

Drawbacks & Risks

风险影响缓解措施
TraceRecord 在超大规模仿真时(>256 芯片)数据量过大内存占用增加、Parquet 文件过大trace_categories 过滤 + 仅在需要时启用追踪
Parquet 依赖引入(pyarrow)Python 包体积增加 ~20MBpyarrow 已是 pandas 常用依赖,且只在写入 trace 时 import
数据库 migration新表需要 schema 迁移SQLAlchemy create_all 自动创建新表,不影响现有表
Rust FFI 新增返回值PyO3 接口变更可选返回(Option<Vec<TraceRecord>>),不破坏现有调用
per-chip 聚合依赖 stats key 的命名约定cdma_chip{i}_unit{j} 格式变化会破坏解析在 adapter 层做格式校验,不匹配时 raise ValueError,报错信息包含实际 key 格式和期望格式

@tbl-spec-obs-11 风险与缓解措施

Success Criteria

场景指标目标值测试方法
8 芯片 Ring AllReduceCommSimResult 包含 per_chip 数据8 个 chip 各有独立的 latency_ns单元测试:提交仿真 -> 检查结果结构
同上stats dict 完整保留cdma_chip{0..7}_unit0.cmd_count 均存在单元测试:检查 stats key 数量 > 0
32 芯片 trace 启用TraceRecord 数量> 1000 条集成测试:trace_enabled=True -> 检查 Parquet 行数
32 芯片 trace 关闭仿真性能无退化耗时增加 < 5%性能测试:trace_enabled=False vs 旧版本
DB 查询按 topology_name + primitive 过滤返回匹配结果,响应 < 100msAPI 测试:GET /evaluation/comm-results?topology_name=X
Parquet 文件32 芯片 1MB AllReduce文件大小 < 1MB集成测试:检查文件大小
straggler 检测人工构造不均衡场景straggler_ratio > 1.1 时正确标记单元测试:构造 per-chip 延迟不均

@tbl-spec-obs-12 验收标准

Future Possibilities

  • 波形可视化 UI(高优先级,前置:本 spec L3 实现完成):前端加载 Parquet trace 文件,用 ECharts 画 link 利用率、buffer 占用、thread 状态时间线。参考 CrossRing 的 WaveformChart 和 FIFOWaveformChart 实现
  • Switch 级 trace(中优先级,前置:本 spec L3 + Switch 模型启用):在 SwitchModel 中增加 VOQ 深度和 iSLIP 仲裁事件的 TraceRecord
  • 实时流式 trace(低优先级,前置:WebSocket 基础设施):仿真过程中实时推送 TraceRecord 到前端,实现"活"的波形显示
  • 跨实验对比 API(中优先级,前置:本 spec L1):支持从多个 experiment 中选取结果做交叉对比,返回对比矩阵

Implementation Notes

本节在实现完成后补充。