12 KiB
MVP TODO - Unity 虚拟地址寻址模拟
此为 MVP 实现,时间要求紧,不需要太考虑代码结构,需要跨脚本访问的内容全用单例也没问题
0. 需求冻结(已确认)
- 模式:单次地址翻译可视化 + 批量访问统计
- 计算机位数:固定
32-bit - 虚拟地址有效位:固定
24-bit - 页大小:固定
4 KB - 访问次数
N:可配置 - TLB:固定
8条全相联 + LRU - 页表:固定二级页表(稀疏结构)
- 物理内存:固定
1 MB(自动换算帧数) - 缺页替换:FIFO
- 指标:TLB 命中率 / 页表命中率 / 缺页次数 / 平均访问开销
- 交互:单步 / 连续播放 / 重置
- 可视化:表格高亮 + 日志时间线 + 简单流程动画
- 技术栈:Unity 2022 + C#
1. 总体分步计划
- Step 1:参数与核心数据模型
- Step 2:地址生成与拆分
- Step 3:TLB(LRU)实现
- Step 4:二级页表与缺页/FIFO
- Step 5:翻译引擎(单步状态机)
- Step 6:统计模块
- Step 7:UI 绑定与流程动画
- Step 8:联调、测试、验收
2. Step 1 - 参数与核心数据模型
TODO
- 创建脚本目录:
Assets/Scripts/Core、Assets/Scripts/Simulation、Assets/Scripts/UI - 新建
SimulationConfig.cs:定义可输入参数 - 新建
ConfigValidator.cs:参数合法性校验 - 新建
AddressParts.cs:保存VPN / offset / L1Index / L2Index - 新建
SimulationState.cs:保存当前轮次、当前虚拟地址、是否缺页等
输入字段(MVP)
machineBits:固定32vaBits:固定24pageSizeKB:固定4physicalMemoryMB:固定1tlbEntries:固定8accessCount:正整数pageFaultPenalty:默认100(抽象开销单位)
校验规则
pageSizeKB必须是 2 的幂offsetBits = log2(pageSizeBytes)且offsetBits < vaBitsframeCount = floor(physicalMemoryBytes / pageSizeBytes)且frameCount >= 1- 非法输入返回明确错误文本(用于 UI 提示)
完成标准
- 给定任意合法参数,能计算全部派生参数并通过校验
- 任意非法输入都能得到可读错误信息
3. Step 2 - 地址生成与拆分
TODO
- 新建
AddressGenerator.cs:生成[0, 2^vaBits - 1]范围虚拟地址 - 新建
AddressTranslatorUtils.cs:拆分VPN + offset - 实现二级页表索引位拆分
拆分规则
vpnBits = vaBits - offsetBitsl1Bits = ceil(vpnBits / 2)l2Bits = floor(vpnBits / 2)- 从
VPN拆出L1Index和L2Index
完成标准
- 控制台可打印每次地址拆分结果
- 固定 24 位 VA 场景下拆分结果正确
4. Step 3 - TLB(全相联 + LRU)
TODO
- 新建
TlbEntry.cs:VPN -> PFN映射及有效位 - 新建
TlbCache.cs:查询、更新、淘汰 - 使用
Dictionary + LinkedList实现 O(1) 级 LRU
行为要求
Lookup(vpn):命中返回 PFN,未命中返回失败InsertOrUpdate(vpn, pfn):已存在则更新并置为最近使用- 超出容量时淘汰最久未使用项
完成标准
- 构造用例可验证 LRU 淘汰顺序正确
- 连续访问时命中统计准确
5. Step 4 - 二级页表 + 缺页 + FIFO
TODO
- 新建
TwoLevelPageTable.cs:Dictionary<L1, Dictionary<L2, PTE>> - 新建
PageTableEntry.cs:PFN / present / dirty(可选) - 新建
PhysicalMemoryManager.cs:空闲帧管理 + FIFO 队列 - 缺页时分配空闲帧;无空闲帧时 FIFO 淘汰
- 淘汰后同步页表项状态(
present = false)
行为要求
- 页表命中:TLB 未命中后,页表中有
present = true映射 - 缺页:页表不存在或
present = false - 装入页面后写回页表并更新 TLB
完成标准
- 能稳定运行大量访问(例如
N=10000)无崩溃 - FIFO 次序可从日志中验证
6. Step 5 - 翻译引擎(单步状态机)
TODO
- 新建
TranslatorEngine.cs - 定义步骤枚举:
GenerateVASplitVALookupTLBLookupPageTableHandlePageFaultComposePAFinalize- 提供
StepOnce()与RunOneAccess()两种执行接口
完成标准
- 单步执行能暂停在每个阶段并暴露当前状态
- 一次完整访问流程结果与预期一致
7. Step 6 - 统计模块
TODO
- 新建
StatsCollector.cs - 累计:
totalAccess、tlbHit、pageTableHit、pageFault - 计算:
tlbHitRate、pageTableHitRate、avgCost
开销模型(MVP)
- TLB 命中:
+1 - TLB miss + 页表命中:
+4 - 缺页:
+4 + pageFaultPenalty
完成标准
- 指标在单步和批量模式下都持续更新
- 批量完成后给出最终汇总
8. Step 7 - UI 绑定与流程动画
TODO
- 新建主场景
Main.unity - 参数面板:固定规格展示(位数/页大小/物理内存/TLB)+ 可调参数(N/开销/地址模式)
- 控制按钮:
单步、连续播放、暂停、重置 - 流程节点 UI:当前步骤高亮(颜色 + 轻动画)
- 表格区:TLB、页表关键条目、FIFO 队列
- 日志时间线:每次访问的关键事件文本
- 指标区:四项核心指标实时显示
字段绑定对照(Step 7)
-
SimulationUiController.configInputView-> 挂有SimulationConfigInputView的对象 -
SimulationUiController.controlView-> 挂有SimulationControlView的对象 -
SimulationUiController.dashboardView-> 挂有SimulationDashboardView的对象 -
SimulationUiController.tablesView-> 挂有SimulationTablesView的对象 -
SimulationUiController.traceView-> 挂有SimulationTraceView的对象(拆分/分支解释) -
SimulationUiController.compactEventView-> 主视图短事件流(建议 5-8 条) -
SimulationUiController.detailTimelineView-> 详细日志时间线(可放在抽屉中) -
SimulationUiController.processHeaderView-> 流程主标题与当前事件 -
SimulationUiController.flowAnimator-> 挂有StepFlowAnimator的对象 -
SimulationUiController.detailDrawerView-> 挂有SimulationDetailDrawerView的对象 -
SimulationUiController.playIntervalSeconds-> 连续播放间隔秒数 -
SimulationConfigInputView.fixedCoreSpecText-> 固定核心规格说明文本(32位机/24位VA/4KB页/1MB物理内存/TLB 8条全相联) -
SimulationConfigInputView.machineBitsInput-> 计算机位数显示输入框(只读,固定32) -
SimulationConfigInputView.vaBitsDropdown-> 虚拟地址位数下拉(只读,固定24) -
SimulationConfigInputView.pageSizeKBInput-> 页大小 KB 输入框(只读,固定4) -
SimulationConfigInputView.physicalMemoryMBInput-> 物理内存 MB 输入框(只读,固定1) -
SimulationConfigInputView.tlbEntriesInput-> TLB 条目数输入框(只读,固定8) -
SimulationConfigInputView.accessCountInput-> 访问次数 N 输入框 -
SimulationConfigInputView.pageFaultPenaltyInput-> 缺页惩罚输入框 -
SimulationConfigInputView.addressModeDropdown-> 地址模式下拉(Random/SequentialArrayLoop) -
SimulationConfigInputView.arrayLengthBytesInput-> 数组总长度(bytes) -
SimulationConfigInputView.arrayElementBytesInput-> 数组元素大小(bytes) -
SimulationConfigInputView.arrayBaseAddressInput-> 数组基址(十进制) -
SimulationControlView.stepButton->单步按钮 -
SimulationControlView.playButton->连续播放按钮 -
SimulationControlView.pauseButton->暂停按钮 -
SimulationControlView.resetButton->重置按钮 -
SimulationDashboardView.stateSummaryText-> 当前步骤/地址拆分/命中状态文本 -
SimulationDashboardView.statsText-> 统计指标文本 -
SimulationDashboardView.errorText-> 参数错误提示文本 -
SimulationTablesView.tlbText-> TLB 表格文本区 -
SimulationTablesView.pageTableText-> 页表关键条目文本区 -
SimulationTablesView.fifoText-> FIFO 队列文本区 -
SimulationTraceView.splitTraceText-> 地址拆分可视化文本 -
SimulationTraceView.pageTableTraceText-> 多级页表查询路径文本 -
SimulationTraceView.decisionReasonText-> 当前分支原因文本 -
SimulationTraceView.pathSummaryText-> 当前访问路径摘要文本 -
SimulationTimelineView.logContainer-> 日志内容容器(建议 VerticalLayoutGroup) -
SimulationTimelineView.logItemPrefab-> 单条日志 TMP_Text 预制体 -
SimulationTimelineView.logScrollRect-> 日志滚动视图 -
SimulationTimelineView.maxLogEntries-> 日志最大保留条数(建议200) -
SimulationProcessHeaderView.currentStepText-> 当前步骤文本(流程主区) -
SimulationProcessHeaderView.currentEventText-> 当前关键事件文本(流程主区) -
SimulationDetailDrawerView.drawerRoot-> 细节抽屉根节点 -
SimulationDetailDrawerView.dashboardTabRoot-> Dashboard 页签内容根节点 -
SimulationDetailDrawerView.tablesTabRoot-> Tables 页签内容根节点 -
SimulationDetailDrawerView.eventsTabRoot-> Events 页签内容根节点(detailEventFlow) -
SimulationDetailDrawerView.openOnStart-> 抽屉是否默认展开 -
SimulationDetailDrawerView.dashboardTabButton-> Drawer 内 Dashboard Tab 按钮 -
SimulationDetailDrawerView.tablesTabButton-> Drawer 内 Tables Tab 按钮 -
SimulationDetailDrawerView.eventsTabButton-> Drawer 内 Events Tab 按钮 -
SimulationDetailDrawerView.closeDrawerButton-> Drawer 内关闭按钮 -
主界面 Info 按钮 ->
SimulationUIController.OpenDetailDrawer() -
StepFlowAnimator.stepNodes(7项)->GenerateVA/SplitVA/LookupTLB/LookupPageTable/HandlePageFault/ComposePA/Finalize节点 -
StepFlowAnimator.stepNodes[].target-> 节点RectTransform -
StepFlowAnimator.stepNodes[].canvasGroup-> 节点CanvasGroup -
StepFlowAnimator.stepNodes[].background-> 节点背景Image -
StepFlowAnimator.accessPulseTarget-> 完整访问完成时做脉冲动画的容器节点
完成标准
- UI 上可完整观察一次访问的每个阶段
- 连续播放期间 UI 不冻结,可暂停/恢复
9. Step 8 - 联调、测试、验收
测试清单
- 参数边界:最小/最大可接受输入
- 固定规格回归:
32位机 + 24位VA + 4KB页 + 1MB物理内存 - 固定规格下参数覆盖:访问次数 / 缺页惩罚 / 地址生成模式
- 小样本可视化:
N=10 - 大样本稳定性:
N=10000 - TLB 固定容量验证:
8条全相联 + LRU 顺序正确 - 物理内存极小场景:高缺页率验证 FIFO
验收标准
- 功能覆盖需求冻结清单
- 四项指标数值可解释且趋势合理
- 单步、连续播放、重置均可稳定使用
- 控制台无持续异常错误
10. 预计工时(MVP)
- Step 1-2:4-6 小时
- Step 3-4:6-10 小时
- Step 5-6:3-5 小时
- Step 7:6-8 小时
- Step 8:2-4 小时
- 合计:约 21-33 小时(约 3-4.5 天)
11. 首日执行建议(直接开工)
- 先完成 Step 1(参数模型 + 校验)
- 紧接 Step 2(地址拆分)
- 当天收尾前完成 Step 3(TLB LRU 最小可运行)