学习路线¶
这套路线按软件工程师真正遇到问题的顺序组织:先建立数据流,再理解状态恢复, 最后把性能现象映射到具体结构。不要一开始就逐文件阅读;大型 Chisel 工程的 参数、Bundle 和生成逻辑会让局部细节失去上下文。
四阶段路线¶
| 阶段 | 目标 | 必读 | 完成标志 |
|---|---|---|---|
| 1. 建图 | 能画出指令与数据的主路径 | 整体微架构、ISA 到流水线 | 能解释前端、后端、MemBlock 的边界 |
| 2. 跟踪 | 能沿源码追踪一条指令 | 前端、后端、访存 | 能从 XSCore 走到关键子模块 |
| 3. 软件可见 | 能解释异常、页表和顺序语义 | Bring-up、Cache 与一致性 | 能定位 reset、trap、TLB flush、fence 路径 |
| 4. 性能归因 | 能提出并验证瓶颈假设 | 性能分析、源码地图 | 每个优化结论都有计数器和源码证据 |
每个模块用同一套问题¶
面对 BPU、ROB、LSQ 或 Cache,都先回答下面六个问题:
- 它维护什么状态? 状态容量、索引和生命周期是什么?
- 请求从哪里来? 上游的
valid/ready、时序和背压条件是什么? - 结果送到哪里? 谁消费,何时算完成,何时对软件可见?
- 失败如何恢复? miss、replay、redirect、flush 或 exception 走哪条路径?
- 如何观测? 有哪些 HPM、
XSPerf、Difftest、ChiselDB 或波形信号? - 软件如何影响? 代码布局、分支、访存局部性、依赖链和同步原语怎样改变它?
建议的第一次源码漫游¶
XSCore.scala
├── frontend/Frontend.scala
│ ├── bpu/Bpu.scala
│ ├── ftq/Ftq.scala
│ ├── icache/ICache.scala
│ ├── ifu/Ifu.scala
│ └── ibuffer/IBuffer.scala
├── backend/Backend.scala
│ ├── CtrlBlock.scala
│ ├── Region.scala
│ ├── ctrlblock/{DecodeStage,Rename,Dispatch}.scala
│ ├── issue/IssueQueue.scala
│ └── rob/Rob.scala
└── mem/MemBlock.scala
├── pipeline/{NewLoadUnit,NewStoreUnit}.scala
├── lsqueue/
├── cache/dcache/
└── cache/mmu/
先只看模块实例化和 IO 连接。第二遍才进入状态机、队列和流水级;第三遍带着一个 具体软件问题阅读,例如“为什么这一类 load 发生 replay”。
建立个人实验记录¶
建议每次实验至少保存:
- 源码 commit、配置类和仿真参数;
- workload、输入、编译器版本与关键编译选项;
mcycle/minstret与相关 HPM 原始值;- 一条可证伪的微架构假设;
- 修改前后的统计显著性,而不只是一组最好结果。
这样站点中的静态知识才能变成可重复的性能工程方法。