181 lines
5.3 KiB
Markdown
181 lines
5.3 KiB
Markdown
# VMdemo
|
||
|
||
一个基于 Unity 的虚拟存储器地址转换可视化项目,用来演示从虚拟地址到物理地址的翻译过程,以及 TLB、二级页表、缺页中断与页面置换在一次内存访问中的作用。
|
||
|
||
项目目标不是做一个“黑盒计算器”,而是把一次地址访问拆成可观察、可暂停、可回放的步骤,方便课程讲解、实验演示和自学理解。
|
||
|
||
## 项目内容
|
||
|
||
当前项目围绕一次虚拟地址访问,提供以下可视化能力:
|
||
|
||
- 单步执行地址翻译流程
|
||
- 连续播放整段访问过程
|
||
- 展示 TLB、页表、FIFO 队列的实时状态
|
||
- 展示当前访问路径、关键决策原因和事件时间线
|
||
- 实时统计 TLB 命中率、页表命中率、缺页次数、平均访问开销
|
||
- 支持不同地址生成方式,观察局部性对命中率的影响
|
||
|
||
## 模拟规格
|
||
|
||
本项目当前采用固定核心规格:
|
||
|
||
| 项目 | 设定 |
|
||
| --- | --- |
|
||
| 机器位数 | 32-bit |
|
||
| 虚拟地址有效位 | 24-bit |
|
||
| 页大小 | 4 KB |
|
||
| 物理内存 | 1 MB |
|
||
| TLB | 8 项,全相联,LRU 替换 |
|
||
| 页表 | 二级页表,稀疏结构 |
|
||
| 页面置换 | FIFO |
|
||
|
||
可调参数主要包括:
|
||
|
||
- 访问次数 `N`
|
||
- 缺页惩罚 `pageFaultPenalty`
|
||
- 地址生成模式
|
||
- 顺序数组访问模式下的数组长度、元素大小、数组基址
|
||
|
||
目前支持两种地址生成模式:
|
||
|
||
- `RandomUniform`:在虚拟地址空间内均匀随机生成地址
|
||
- `SequentialArrayLoop`:按数组元素顺序循环访问,适合观察局部性
|
||
|
||
## 地址翻译流程
|
||
|
||
项目中的翻译引擎按以下步骤推进:
|
||
|
||
1. `GenerateVA`:生成本轮虚拟地址
|
||
2. `SplitVA`:拆分出 `VPN / offset / L1 / L2`
|
||
3. `LookupTLB`:查询 TLB
|
||
4. `LookupPageTable`:TLB 未命中后查询二级页表
|
||
5. `HandlePageFault`:页表未命中时分配页框并处理 FIFO 置换
|
||
6. `ComposePA`:合成物理地址
|
||
7. `Finalize`:记录统计信息并结束本轮访问
|
||
|
||
访问开销模型如下:
|
||
|
||
- TLB 命中:`+1`
|
||
- TLB miss + 页表命中:`+4`
|
||
- 缺页:`+4 + pageFaultPenalty`
|
||
|
||
## 可视化界面
|
||
|
||
主场景中会展示几类关键信息:
|
||
|
||
- 控制区:单步、连续播放、暂停、重置
|
||
- 配置区:访问次数、缺页惩罚、地址生成模式等输入
|
||
- 流程区:当前处于哪一个地址翻译步骤
|
||
- 表格区:TLB、页表关键项、FIFO 队列
|
||
- 追踪区:地址拆分、查询路径、当前决策原因
|
||
- 时间线区:每轮访问的事件日志
|
||
- 统计区:命中率、缺页次数、平均开销
|
||
|
||
## 技术栈
|
||
|
||
- Unity `2022.3.62f3c1`
|
||
- C#
|
||
- TextMesh Pro
|
||
- Unity UI
|
||
- Unity Test Framework
|
||
- DOTween
|
||
|
||
## 运行方式
|
||
|
||
### 1. 打开项目
|
||
|
||
使用 Unity Hub 安装并选择 `Unity 2022.3.62f3c1`,然后打开项目根目录:
|
||
|
||
```text
|
||
C:\UnityProjects\VMdemo
|
||
```
|
||
|
||
### 2. 打开主场景
|
||
|
||
在 Unity 中打开:
|
||
|
||
```text
|
||
Assets/Scenes/Main.unity
|
||
```
|
||
|
||
### 3. 运行
|
||
|
||
点击 Play 后:
|
||
|
||
1. 根据需要调整访问次数、缺页惩罚和地址模式
|
||
2. 点击“单步”逐阶段观察地址翻译
|
||
3. 点击“连续播放”观察批量访问统计变化
|
||
4. 点击“暂停”或“重置”中断当前模拟
|
||
|
||
## 项目结构
|
||
|
||
```text
|
||
Assets/
|
||
Scenes/ 主场景
|
||
Scripts/
|
||
Core/ 配置、校验、地址拆分等基础模型
|
||
Simulation/ TLB、页表、物理内存、翻译引擎、统计模块
|
||
UI/ 界面控制、表格渲染、日志时间线、流程动画
|
||
Tests/
|
||
EditMode/ 核心逻辑的编辑器测试
|
||
doc/ 讲解材料、设计草稿与 TODO
|
||
Packages/ Unity 包依赖
|
||
ProjectSettings/ Unity 项目设置
|
||
```
|
||
|
||
## 关键脚本
|
||
|
||
- `Assets/Scripts/Core/SimulationConfig.cs`:模拟配置与固定规格定义
|
||
- `Assets/Scripts/Core/ConfigValidator.cs`:参数合法性校验与派生量计算
|
||
- `Assets/Scripts/Simulation/TranslatorEngine.cs`:地址翻译主流程状态机
|
||
- `Assets/Scripts/Simulation/TlbCache.cs`:TLB 查询与 LRU 替换
|
||
- `Assets/Scripts/Simulation/TwoLevelPageTable.cs`:二级页表实现
|
||
- `Assets/Scripts/Simulation/PhysicalMemoryManager.cs`:页框分配与 FIFO 管理
|
||
- `Assets/Scripts/Simulation/StatsCollector.cs`:统计指标计算
|
||
- `Assets/Scripts/UI/SimulationUIController.cs`:主界面交互与数据绑定
|
||
|
||
## 测试
|
||
|
||
项目包含一组编辑器测试,覆盖核心逻辑:
|
||
|
||
- Step 1:参数与核心数据模型
|
||
- Step 2:地址拆分
|
||
- Step 3:TLB 与 LRU
|
||
- Step 4:二级页表与 FIFO 置换
|
||
- Step 5:翻译引擎状态机
|
||
- Step 6:统计模块
|
||
|
||
相关测试位于:
|
||
|
||
```text
|
||
Assets/Tests/EditMode
|
||
```
|
||
|
||
可在 Unity Test Runner 中运行 EditMode Tests。
|
||
|
||
## 适用场景
|
||
|
||
这个项目适合用于:
|
||
|
||
- 操作系统课程中讲解虚拟存储器和地址翻译流程
|
||
- 展示 TLB 命中、页表命中、缺页之间的区别
|
||
- 对比随机访问与顺序访问对局部性的影响
|
||
- 作为后续扩展页面置换算法、页表结构或缓存模型的基础工程
|
||
|
||
## 后续可扩展方向
|
||
|
||
- 增加更多页面置换算法,例如 LRU / Clock
|
||
- 增加多种页表组织方式的切换
|
||
- 加入更细的访问耗时模型
|
||
- 增加截图、录屏或实验报告导出能力
|
||
- 增加更多教学案例预设
|
||
|
||
## 文档
|
||
|
||
仓库中的 `doc/` 目录保存了开发过程中的讲解资料与草稿,例如:
|
||
|
||
- `doc/MVP-TODO.md`
|
||
- `doc/dialog.md`
|
||
|
||
这些文档更偏向设计记录,正式使用说明以本 README 为准。
|