
这张流程图展示了完整的地址转换和数据访问流程,结合缺页的那篇能搞清楚内存访问的完整链路。
内存访问的实际路径
CPU要访问内存,走这么几步:
第一步:TLB查询
虚拟地址拆成「虚页号 + 页内偏移」。MMU拿虚页号去TLB里比对标签。
- 命中:直接拿到物理页框号,拼成物理地址,进入下一步
- 缺失:触发TLB缺失异常,操作系统去内存查页表,找到映射后填入TLB,然后重试这条指令
第二步:Cache查询
有了物理地址,才能去查Cache。注意,Cache是用物理地址索引的(物理Cache),不是虚拟地址。
- 命中:数据直接返回CPU
- 缺失:从主存调数据块进Cache,再返回CPU
第三步:写操作的权限检查
如果是写操作,TLB命中时还要检查页表项的写权限位。试图写只读页?触发保护异常,操作系统介入,通常结果是SIGSEGV。
关键依赖关系
TLB命中是Cache查询的前提。没有物理地址,Cache根本不知道去哪儿找数据。所以一次成功的内存访问, ideally 要连续命中TLB和Cache。
两次都命中是最快路径:1个周期(TLB)+ 几个周期(Cache)就能拿到数据。任一环节缺失,延迟就上去了。
几个优化点
| 写磁盘慢 | 写回+脏位 | 页被修改才标记脏,换出时才写盘,减少I/O |
| 地址转换慢 | TLB | 缓存近期映射,命中就省掉内存访问 |
| 转换+访问衔接 | TLB和Cache流水线 | 前一周期TLB转换,下一周期Cache查询,重叠执行 |
TLB vs 页表
| 本质 | 专用cache | 完整的数据结构 |
| 目的 | 加速转换 | 提供权威映射 |
| 位置 | CPU内部(SRAM) | 主存(DRAM) |
| 速度 | ~1周期 | >100周期 |
| 内容 | 页表的子集(热点映射) | 全部虚拟页的映射 |
| 管理 | 硬件(MMU)自动维护 | 操作系统创建维护 |
TLB对软件透明,除了进程切换时要刷新或切换上下文。页表对软件可见,操作系统通过修改页表来控制内存映射和权限。
一个细节
有些架构用虚拟索引的Cache(VIVT或VIPT),可以并行查TLB和Cache,进一步降低延迟。但物理索引的Cache(PIPT)实现简单,避免别名问题。Intel Xeon和AMD Zen都采用了VIPT作为其L1数据缓存的方案,采用PIPT作为L2/L3的方案。
TLB命中看起来只是地址转换环节的一个分支判断,但它决定了后续所有步骤的走向。miss的代价是百周期级别,所以TLB的设计(项数、关联度、替换策略)对系统性能影响很大。
写在最后
缺失堵塞后会出现什么情况?



