9.6.1 结合高速缓存和虚拟内存

好的,我们来通过一个具体的例子说明物理寻址和虚拟寻址的 SRAM 高速缓存的区别。

核心概念简述

  • 虚拟地址 (Virtual Address, VA):由 CPU 发出的、程序看到的地址。每个进程都有自己独立的虚拟地址空间。
  • 物理地址 (Physical Address, PA):在物理内存(DRAM)上的实际地址。整个系统只有一套物理地址空间。
  • SRAM 高速缓存:位于 CPU 和主存(DRAM)之间,用于加速内存访问的小而快的存储器。

场景设定

假设我们有两个进程:进程 A进程 B
它们通过操作系统的内存管理,共享了同一块物理内存页(例如,这是一个共享库的代码段)。具体来说:

  • 进程 A 将此共享页映射到其虚拟地址空间的 0x4000 处。
  • 进程 B 将此共享页映射到其虚拟地址空间的 0x8000 处。
  • 这块共享内容在物理内存中的实际位置是 0x12345000

现在,进程 A 和进程 B 都要读取这个共享页开头的一个字(word)data


例子 1:物理寻址的高速缓存 (Physically Addressed Cache)

这是大多数现代系统的选择(如 x86, ARM)。

工作流程:

  1. 进程 A 发出读取虚拟地址 VA=0x4000 的指令。

  2. MMU(内存管理单元) 介入,通过查询进程 A 的页表,将 VA=0x4000 翻译PA=0x12345000。同时,MMU 会检查进程 A 是否有该地址的读取权限(保护机制在此完成)。

  3. CPU 现在要获取物理地址 PA=0x12345000 的数据。

  4. 缓存 检查是否存在标签为 0x12345000 的数据。我们假设缓存miss,于是从物理内存 0x12345000 处将 data 加载到缓存中。缓存的标签是物理地址 0x12345000

  5. 进程 A 的请求被满足。

  6. 稍后,进程 B 发出读取虚拟地址 VB=0x8000 的指令。

  7. MMU 介入,通过查询进程 B 的页表,将 VB=0x8000也翻译PA=0x12345000(因为它们是共享的同一物理页)。同时检查进程 B 的权限。

  8. CPU 现在也要获取物理地址 PA=0x12345000 的数据。

  9. 缓存 再次检查标签 0x12345000,发现缓存命中 (Hit)! 因为之前进程 A 的访问已经把 data 缓存了。

  10. 缓存直接将 data 返回给 CPU,进程 B 的请求被极大地加速

物理寻址的优势体现:

  • 共享天然高效:尽管进程 A 和 B 使用不同的虚拟地址(0x4000 vs 0x8000),但缓存只认最终的物理地址(0x12345000)。数据在缓存中只有一份副本,所有共享该物理页的进程都能受益,缓存利用率高。
  • 保护简单:缓存完全不需要关心“当前是哪个进程在访问”或“这个虚拟地址是否有权限”。保护检查由 MMU 在地址翻译阶段统一完成。缓存只是一个“傻傻的”、基于物理地址的快取,设计简单高效。

例子 2:虚拟寻址的高速缓存 (Virtually Addressed Cache)

这种设计较少见,但在一些早期处理器或特定场合(如 TLB 之后的一级指令缓存)存在。

工作流程:

  1. 进程 A 发出读取虚拟地址 VA=0x4000 的指令。

  2. CPU 直接使用这个虚拟地址 VA=0x4000 去查询缓存(MMU 尚未进行地址翻译)。

  3. 缓存 检查是否存在标签为 VA=0x4000 的数据。假设缓存miss,这时才去启动 MMU 进行地址翻译,得到 PA=0x12345000,然后从物理内存加载 data此时,缓存的标签是虚拟地址 0x4000

  4. 进程 A 的请求被满足。

  5. 稍后,进程 B 发出读取虚拟地址 VB=0x8000 的指令。

  6. CPU 直接使用虚拟地址 VB=0x8000 去查询缓存。

  7. 缓存 检查标签 VB=0x8000,发现缓存 miss!因为缓存里存储的是标签为 VA=0x4000 的数据(进程 A 留下的),虽然它们指向相同的物理数据

  8. 于是流程需要从头再来:启动 MMU 翻译 VB=0x8000 -> PA=0x12345000,然后从内存(或者另一个进程的缓存条目?)加载数据。缓存中现在可能有了两份相同数据的副本,一份标签为 0x4000(属于进程 A),另一份标签为 0x8000(属于进程 B)。

posted @ 2025-08-22 08:38  最爱丁珰  阅读(8)  评论(0)    收藏  举报