虚拟内存概述

1.内存的痛点

内存不足【Not Enough Memory】

32位处理器架构为每个程序【Program】提供了专属自己的 32 位地址,当通过load和store 指令操作字【word】时,我们可以指定一个 32 位地址,因此,这意味着程序【Program】可以访问 32 位地址空间中的任意字节。而 32 位地址仅仅能访问 4GB【2^{_{32}} byte】 内存。如果我们的内存不足 4GB ,会出现内存访问失败。

内存碎片

现在操作系统都是支持多道程序【multiprogramming】的,多个程序共享物理内存。

内存安全

每个程序都可以访问任意 32 位的内存地址,如果多个程序访问同一块内存地址,他们会互相影响,从而导致安全隐患。

如果所有的程序都可以访问相同的 32 位内存空间,内存存在如下问题

  • 内存不足
  • 内存碎片
  • 内存安全

那如何解决这个问题???

任何计算机科学中的问题,都可以通过添加中间层来解决!

问题的关键点在于所有程序共享的是“相同的 32 位内存空间” ,我们可以通过为每个程序提供专属于自己的内存虚拟内存空间【virtual memory space】,然后单独的将该虚拟内存空间【virtual memory space】映射到物理内存空间【RAM memory space】上(如果内存耗尽,我们可以将其移动到磁盘中)。

2.什么是虚拟内存

在没有虚拟内存之前,程序地址【Program Address】 = 物理地址【RAM Address】。

虚拟内存作为中间层,将程序地址【Program Address】映射到物理地址【RAM Address】,来解决痛点。

下面我们来看虚拟内存是如何解决内存的三个痛点的。

内存不足【Not Enough Memory】

  • 将部分程序地址空间【Program Address Space】映射到磁盘【Disk】
  • 需要的话,我们可以将其加载进内存

当程序访问的内存地址超过物理内存空间时,由于虚拟内存的存在,我们可以首先通过驱逐策略,将内存中最旧的数据通过页换出【Page Out】移动到磁盘中,并更新虚拟内存页表中的映射关系,将对应的虚拟内存地址映射到磁盘。然后通过页换入【Page In】,将本次访问的数据由磁盘【Disk】移动到内存中,并更新对应的虚拟内存映射关系。

需要注意的是,磁盘的访问速度,大概是RAM速度的1000x,任何时候,当你不能把你的数据放入内存,而必须访问磁盘,你必将为此付出了巨大的性能损失。

内存碎片

多道程序设计的操作系统上,当某个程序退出时,虚拟内存是可以通过灵活的映射,解决由内存碎片导致的内存空间不连续的问题。

内存安全

虚拟内存通过将每个程序的程序地址【Program Address】分别映射到不同的物理地址,解决了多个程序同时访问同一内存地址带来的内存安全问题。

虚拟内存让我们可以对多道程序实现完全隔离,使它们无法相互共享/损坏数据。但是这也带来一个弊端,即程序之间无法共享数据了?其实不然,我们可以通过使用相同的映射,就可以实现程序间共享,即将程序地址【Program Address】均映射到相同的物理地址【RAM Address】上。

3.虚拟内存是如何工作的

基本思想:分离地址空间

  • 虚拟内存【VA】:程序所看到的,它是由处理器架构决定的,在 32 位处理架构上,虚拟内存空间就是 0 ~ 2^{32} - 1
  • 物理内存【PA】:计算机上的物理RAM,如果电脑上安装的是 2GB 内存,那么物理内存空间就是 0 ~ 2^{31} - 1

程序实如何访问内存的?

 

 

  1. 程序执行一个load命令,并指定一个虚拟地址
  2. 计算机将虚拟地址转换为物理地址
  3. 如过物理地址不存在于内存上,操作系统会将其从磁盘中加载到内存中
  4. 计算机使用物理地址读取RAM中的数据,并将数据返回给程序

4.页表

页表是用于追踪虚拟内存到物理内存之间映射的。对于每一个虚拟地址【Virtual Address】,页表中都存在其对应的一条页表项【Page Table Entry,PTE】。

那么,在 32 位架构上,一个页表需要有多少个页表项【Page Table Entry,PTE】呢?

答案是:2^{30} ,大约为10亿条,我们假设每个页表项【PTE】只存储物理地址,用索引标识对应的虚拟地址,则大概至少占用 4GB(2^{30} * 32 = 2^{30} * 4B = 2^{32}B = 4GB) 内存。因为内存是字对齐的,在 32 位架构上,CPU 一个字的大小是 32 位,即 4 bytes。而虚拟内存总大小为 2^{32} ,因此 2^{32} / 4 = 2^{30}

陷入了困境~

解决方案:将内存按照块【Block】/页【Page】来划分,而不是字【Word】。

下面以 4KB 的页来举例:

 页表通过管理以块【Block】/页【Page】为单位组织的数据,解决了以字【Word】为单位组织数据带来的问题,在以 4KB 为页大小的情况下,即一页包括 1024(2^{10}) 个字,页表项【PTE】的总数锐减到 2^{20} 条,大约为 100 万条,大概占用 2^{22}B,大约为 4MB。 

  • 使用更少的页表项【PTE】就可以覆盖整个内存空间
  • 但是在RAM的使用上降低了灵活性(页换入/页换出)

5.地址转换

前提:

  • 32 位机器 
  • 256MB RAM
  • 4KB 页大小

因此:

  • 32 位虚拟内存地址
  • 28 位物理内存地址

我们来看一下Page、Offset之间的转换示意图:

6.地址转换走查

 当虚拟地址在页表欧中有映射时:

当虚拟地址在页表中无映射时:

需要注意的,Offset Size 完全由页大小控制:

  • 在页大小 = 4KB 时,Offset Size 占用 12 位
  • 当页大小 = 64KB 时,Offset Size 占用 16 位

7.Page Fault

当虚拟地址请求的数据不在RAM中时,发生了什么?

  • 【1 cycle】页表项【PTE】说该页不在RAM中,而时再磁盘上
  • 【100 cycle】硬件(即CPU)生成一个缺页异常【Page Fault Exception】
  • 【10000 cycle】操作系统捕获该异常,并跳转到缺页处理程序【Page Fault Handler】清理该异常,操作系统会负责分析是哪个页导致的缺页以及它在磁盘上的位置,并将其从磁盘加载到 RAM 上
    • 操作系统首先选择一个页,将其从 RAM 中驱逐出去(这里设置到内存驱逐策略,比如FIFO,LIFO)
    • 【40000000 cycle】如果驱逐的页是脏的【Drity】,它需要首先写回到磁盘上
    • 【40000000 cycle】操作系统将新页从磁盘中读取出来,并加载到 RAM 中
    • 【1000 cycle】操作系统变更页表项【PTE】,标识其映射关系
  • 【10000 cycle】操作系统跳转回导致缺页异常的指令处,此时不会再触发缺页异常,因为响应的页已经加载到了 RAM 中

因此,一个缺页,需要花费 8000 万个机器周期

缺点:触发缺页时非常慢

优点:不再会因为内存不足而崩溃

8.内存安全

如果每个应用程序都拥有专属于自己的页表,那么它可以将每个程序的虚拟地址【VA】,映射到唯一的物理地址【PA】,但是这也导致程序间无法共享数据。

在32位Linunx上,程序的地址空间如图所示:

 通过虚拟内存映射,我们可以实现隔离与共享:

那么虚拟内存到底是如何提供分别映射【Separate Mapping】的呢?

  • 每个进程都有其专属的页表
  • 操作系统确保只有在我们希望共享时,才映射到同一物理地址

9.更快地虚拟内存

虚拟内存的开销(每个指令平均访问内存1.33次):

  • 访问 RAM 中的页表
  • 地址转换:VA -> PA
  • 访问由物理地址指定的 RAM 内存

解决方案:页表缓存【Page Table Cache】,该技术被称为转译后备缓冲器【Translation Lookaside Buffer】

为了保证速度,转译后备缓冲器【Translation Lookaside Buffer,TLB】通常都很小:

  • 将 TLB 按照指令【iTLB】和数据用【dTLB】户分开
  • 通常有 64 项,4-way( 4KB 页大小)
  • 或者有 32 项,4-way( 2MB 页大小)

TLB 太小了,我们如何才能使其变大,而不影响性能呢?

  1. 设置更大的页大小:4KB 页大小,TLB 支持 64 项 ,只能覆盖到 256KB 大小的内存,而如果使用 2MB 的页大小,TLB 支持 32 项,则能覆盖到 64MB 大小的内存
  2. 增加二级 TLB,许多处理器确实也是这么做的,L2 TLB 大约数 L1 TLB 的8倍,时间开销则大概是是两倍
  3. 硬件自动填充 TLB:这也被称为“Hardware Page Table Walk”,基本上,硬件假设页表以一种特殊的形式驻留在内存中,它可以在 TLB miss 时,从页表获取数据,而不需要进入操作系统处理流程中

10.TLB是如何工作的

前提:

  • 32 位虚拟地址空间
  • 4KB 页大小

TLB empty 

当 TLB 为空的时候:

  • 虚拟地址中的低 12 位(Virtual Page Offset)无需转换
  • 虚拟地址中的高 24 位(Virtual Page Number)进入 TLB
    • 因为 TLB 为空,因此触发 TLB miss
    • 从 RAM 中加载页表项【PTE】到 TLB
    • 完成地址转换
  • 访问由物理地址所指定的 RAM 

TLB miss 

 

 

TLB miss + eviction 

 

TLB miss + eviction + Disk 

 

11.多级页表

对于一个4KB 页大小的 32 位机器而言:

  • 1M 个页表项【PTE】(32 位中,12 位用于 Page Offset,剩余 20 位,2^{20} = 1M
  • 每一个页表项【PTE】大约需要占用 4 字节(20 字节用于物理页码,其他的用于授权位)
  • 大概需要占用 4MB

但是因为每个程序都有其专属的页表,如果我们有100个程序,那么大概需要 4MB * 100 = 400MB,而最艰难的是,我们不能将页表页换出【Page Out】到磁盘上!因为如果页表不在 RAM 中,我们没有办法访问它。

那如何解决这个问题???

任何计算机科学中的问题,都可以通过添加中间层来解决!

多级页表【Multi-Level Page Table】

首先是一级页表【L1 Page Table】,该页表大小为 4KB ,共计 1024 个页表项【PTE】,它用于指向其他页。

然后是二级页表【L2 Page Table】,该页表大小为 4KB ,共计 1024 个页表项【PTE】。

 

通过一二级页表,我们便可以将页表换出到磁盘上,不再需要始终保持在 RAM 中。

需要注意的是,一级页表必须始终驻留在 RAM 中,这样我们才能定位到其他页表!!!

多级页表是如何工作的?

 

12.TLB AND Cache

TLB 和 CPU Cache 可以以两种方式协作!!

物理缓存

顾名思义,即 CPU 缓存是基于物理地址缓存的:

  • CPU 生成虚拟地址
  • TLB 将虚拟地址映射为物理地址
  • 物理地址命中 CPU Cache,则返回数据,否则继续向下走
  • 根据物理地址访问 RAM

缺点:

  • 慢,在访问 CPU Cache 前必须做一次 TLB 映射

 

虚拟缓存

顾名思义,即 CPU 缓存是基于虚拟地址缓存的

  • CPU 生成虚拟地址
  • 虚拟地址命中 CPU Cache,则返回数据,否则继续向下走
  • TLB 将虚拟地址映射为物理地址
  • 根据物理地址访问 RAMA

优点:

  • 快,只有在 Cache miss 时才需要做 TLB 映射

 缺点:

  • 虚拟 CPU Cache 是基于虚拟内存实现的缓存,所以基于虚拟地址的保护不能让应用程序区分开来

合二为一 VIPT【Virtually Indexed Physically Tagged】

在 VIPT 中同时操作 TLB 转换【TLB Translation】和缓存查找【Cache Lookup】。

  • 使用虚拟页码【virtual page number】进行 TLB 转换【TLB Translation】
  • 使用页偏移【Page Offset】进行缓存查找【Cache Lookup】
  • TLB 转换得到物理地址【Physically Address】
  • 缓存查找获得物理标签【Physical Tag】
  • 如果物理地址【Physically Address】 == 物理标签【Physical Tag】,则缓存命中

优点:

  • 快, TLB 转换【TLB Translation】和缓存查找【Cache Lookup】是同时做的
  • 安全,只有物理地址与物理标签匹配时才命中

缺点:

  • 只能使用页偏移【Page Offset】来索引缓存,这限制了缓存大小的上限
  • 目前很多处理器使用 VIPT 来实现 L1 缓存

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值