[CSAPP笔记][第九章虚拟存储器][十分核心]

9.虚拟存储器

为了更加有效地管理存储器且少出错,现代系统提供了对主存的抽象概念,叫做虚拟存储器(VM)

  • 虚拟存储器是硬件异常,硬件地址翻译,主存,磁盘文件和内核软件的完美交互。
  • 为每个进程提供一个大的一致的私有的地址空间。
  • 提供了3个重要能力。

    • 将主存看成磁盘地址空间的高速缓存
      • 只保留了活动区域,并根据需要在磁盘和主存间来回传送数据,高效使用主存。
    • 为每个进程提供一致的地址空间

      • 简化存储器管理
    • 保护了每个进程的地址空间不被其他进程破坏。

  • 程序员为什么要理解它?

    • 虚拟存储器是中心的。
      • 遍布在计算机系统所有层次,硬件异常,汇编器,连接器,加载器,共享对象,文件和进程中扮演重要角色。
    • 虚拟存储器是强大的。

      • 可以创建和销毁存储器片(chunk)
      • 将存储器片映射到磁盘文件的某个部分。
      • 其他进程共享存储器。
      • 例子
        • 能读写存储器位置来修改磁盘文件内容。
        • 加载文件到存储器不需要显式的拷贝。
    • 虚拟存储器是危险的

      • 引用变量,间接引用指正,调用malloc动态分配程序,就会和虚拟存储器交互。
      • 如果使用不当,将遇到复杂危险的与存储器有关的错误。
      • 例子
        • 一个带有错误指针的程序可以立即崩溃于段错误或者保护错误
        • 运行完成,却不产生正确结果。
  • 本章从两个角度分析。

    • 虚拟存储器如何工作。
    • 应用程序如何使用和管理虚拟存储器

9.1 物理与虚拟寻址

  • 物理地址(Physical Address,PA):计算机系统的主存被组织为M个连续的字节大小的单元组成的数组。每个字节的地址叫物理地址.

  • CPU访问存储器的最自然的方式使用物理地址,这种方式称为物理寻址
    - 早期的PC,数字信号处理器,嵌入式微控制器以及Cray超级计算机使用物理寻址

  • 现代处理器使用的是虚拟寻址(virtual addressing)的寻址形式。

    • CPU通过生成一个虚拟地址(Virtual address,VA)来访问主存。

      • 虚拟地址转换为物理地址叫做地址翻译(address translation)
    • 地址翻译也需要CPU硬件和操作系统之间的紧密结合。

      • CPU芯片上有叫做存储器管理单元(Memory Management Unit,MMU)的专用硬件。
        • 利用存储在主存中的查询表来动态翻译虚拟地址。
        • 查询表由操作系统管理。

9.2 地址空间

地址空间(address space)是一个非负整数地址的有序集合。

  • 如果地址空间中整数是连续的,我们说它是线性地址空间(linear address space)

    • 为了简化讨论,我们总是假设使用线性地址空间。
  • 在一个带虚拟存储器的系统中,CPU从一个有N=2^n个地址的地址空间中生成虚拟地址,这个地址空间称为虚拟地址空间(virtual address space)

  • 一个地址空间大小是由表示最大地址所需要的位数来描述的。

    • N=2^n个地址的虚拟地址空间叫做n位地址空间。
    • 现在操作系统支持32位64位
  • 一个系统还有物理地址空间,它与系统中物理存储器的M=2^m(假设为2的幂)个字节相对应。

地址空间的概念很重要,因为它区分了数据对象(字节)和 它们的属性(地址)

  • 每个字节(数据对象)一般有多个 独立的地址(属性)。每个地址都选自不同的地址空间。
    • 比如一般来说。
      • 字节 有一个在虚拟地址空间虚拟地址
      • 还有一个在物理地址空间物理地址
      • 两个地址都能访问到这个字节
    • 类似现实世界的门牌号, 和经纬度

9.3 虚拟存储器作为缓存的工具

感悟

在讲述这一小章之前,必须交代一下我对虚拟存储器概念的存疑
原本我以为虚拟存储器=虚拟内存
以下是虚拟内存的定义

虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换

而在下面的定义我们可以看到CSAPP中认为虚拟存储器是存放在磁盘上的。
在此,我们姑且当做两者是不同的东西,以后有更深刻的理解,再思考。

虚拟存储器(VM)被组织为一个存放在磁盘上的N个连续字节大小的单元组成的数组。

  • 每个字节都有一个唯一的虚拟地址,这个虚拟地址作为到数组的索引。
  • 磁盘上数组的内容被缓存到主存中。

    • 同存储器层次结构其他缓存一样,磁盘上的数据被分割称
      • 这些作为磁盘和主存之间的传输单元。
      • 虚拟页(Virtual Page,VP)就是这个
        • 每个虚拟页大小为P=2^p字节。
    • 物理存储器被分割为物理页,大小也为P字节
      • 也被称为页帧(page frame)
  • 任何时候,虚拟页的集合都被分为3个不相交的子集

    • 未分配的:VM系统还未分配(或者创建)的页。未分配的没有任何数据与之相关联。
      • 不占用磁盘空间
      • 通过malloc来分配
    • 缓存的:当前缓存在物理存储器的已分配页。
    • 未缓存的:没有缓存在物理页面存储器中的已分配页。

9.3.1 DRAM缓存的组织结构

DRAM表示虚拟存储器系统的缓存,在主存中缓存虚拟页,有两个特点。

  • DRAM缓存不命中处罚十分严重。
    • 因为磁盘DRAM慢100000多倍。
  • 访问一字节开销
    • :从一个磁盘的一个扇区读取第一个字节的时间开销要比从该扇区中读连续的字节慢大约100000倍

DRAM缓存的组织结构由这种巨大的不命中开销驱动。因此有以下特点。
(有些地方不是特别懂,之后看完第六章应该会好点)

  • 虚拟页往往很大。

    • 4KB~2MB
    • 访问一字节开销的原因才要这么大。
  • DRAM缓存是全相联

    • 也就是: 任何虚拟页都能放在任何物理页中。
    • 原因在于大的不命中惩罚
  • 更精密的替换算法

    • 替换错了虚拟页的惩罚很高。
  • DRAM缓存总是写回

    • 因为对磁盘的访问时间很长
    • 而不用直写

9.3.2 页表

判断命中替换又多种软硬件联合提供。

  • 操作系统软件,MMU中的地址翻译硬件和页表(page table)

    • 页表是存放在物理存储器的数据结构。

      • 页表将虚拟页映射到物理页。
      • 地址翻译硬件将虚拟地址转换为物理地址都会读取页表
    • 操作系统负责维护页表的内容,以及磁盘及DRAM之间来回传送页。

  • 页表就是一个页表条目(Page Table Entry,PTE)的数组.
    • 虚拟地址空间 中每个页在页表的固定偏移量处都有一个PTE.
    • 每个PTE由一个有效位n位地址字段
      • 有效位表明虚拟页是否被缓存。
        • 如果有效位存在,那么地址字段指向对应的物理存储器。
        • 如果有效位不存在。
          • 地址字段要么为NULL
          • 要么指向虚拟页在磁盘所在的位置。

9.3.3 页命中

  • 一个页命中的过程
  • 一个虚拟地址转换为物理地址的过程。

9.3.4 缺页

在虚拟存储器的习惯说法中,DRAM缓存不命中称为缺页

处理过程如下:

  • 读取虚拟地址所指向的PT
  • 读取PTE有效位,发现未被缓存,触发缺页异常
  • 调用缺页异常处理程序

    • 选择牺牲页。
    • 如果牺牲页发生了改变,将其拷贝回磁盘(因为是写回)
    • 需要读取的页代替了牺牲页的位置。
    • 结果:牺牲也不被缓存,需要读取的页被缓存。
  • 中断结束,重新执行最开始的指令。

  • DRAM中读取成功。

虚拟存储器是20世纪60年代发明的,因此即使与SRAM缓存使用了不同的术语。

  • 被称为
  • 磁盘DRAM之间传送的活动叫做交换(swapping)或者页面调度(paging)
  • 不命中发生时,才换入页面,这种策略叫做按需页面调度(demand paging)
    • 现代系统基本都是用这个。

9.3.5 分配页面

比如某个页面所指向地址为NULL,将这个地址指向磁盘某处,那么这就叫分配页面

此时虚拟页未分配状态 变为 未缓存

9.3.6 又是局部性拯救了我们

虚拟存储器工作的相当好,主要归功于老朋友局部性(locality)

尽管从头到尾的活动页面数量大于物理存储器大小。

但是在局部内,程序往往在一个较小的活动页面集合工作

  • 这个集合叫做工作集(working set)或者叫常驻集(resident set)

    • 初始载入开销比较大。
  • 程序有良好的时间局部性虚拟存储器都工作的相当好。

  • 如果程序实在很烂,或者物理空间很小,工作集大于物理存储器大小。这种状态叫颠簸(thrashing).
    • 这时,页面不断换进换出。性能十分低。

统计缺页次数
可以利用Unix的getrusage函数检测缺页数量。

9.4 虚拟存储器作为存储器的管理工具

实际上,操作系统为每个进程提供一个独立的页表

因此,VM简化了链接加载,代码数据共享,以及应用程序的存储器分配。

  • 简化链接

    • 独立的空间地址意味着每个进程的存储器映像使用相同的格式。

      • 文本节总是从0x08048000(32位)处或0x400000(64位)处开始。
      • 然后是数据,bss节,栈。
    • 一致性极大简化了链接器的设计和实现。

  • 简化加载

    • 加载器可以从不实际拷贝任何数据从磁盘到存储器。
    • 基本都是虚拟存储系统完成。

    将一组连续的虚拟页映射到任意一个文件中的任意位置的表示法称作存储器映射。Unix提供一个称为mmap的系统调用,允许程序自己做存储器映射。在9.8详细讲解。

  • 简化共享

    • 独立地址空间为操作系统提供了一个管理用户进程和操作系统自身之间的一致共享机制.
    • 例子
      • 操作相同的操作系统内核代码
      • C标准库的printf.
    • 因此操作系统需要将不同进程的适当的虚拟页映射到相同的物理页面。
      • 多个进程共享这部分代码的一个拷贝。
      • 而不是每个进程都要加载单独的内核和C标准库的拷贝。
  • 简化存储器分配.

    • 虚拟页连续(虚拟页还是单独的),物理页可以不连续。使得分配更加容易。
  • 9.5 虚拟存储器作为存储器保护的工具

    任何现代操作系统必须为操作系统提供手段来控制存储器系统的访问。

    • 不应该允许用户进程修改它的只读文本段。
    • 不允许它读或修改任何内核的代码和数据结构
    • 不允许读写其他进程的私有存储器。
    • 不允许修改共享的虚拟页,除非所有共享者显示允许这么做(通过调用明确的进程间通信

    方式:在PTE上添加一些格外的许可位来控制访问。

    • SUP:是否只有在内核模式下才能访问?
    • READ:读权限。
    • WRITE:写权限。

    如果指令违反了许可条件,触发一般保护性异常,然后交给异常处理程序Shell一般会报告为段错误(segmentaion fault)

    9.6 地址翻译

    认识到硬件在支持虚拟存储器中的角色

    以下是接下来可能要用到的符号,作参考。

    • 形式上来说,地址翻译是一个N元素的虚拟地址空间(VAS)中的元素和一个M元素的物理地址空间(PAS)元素之间的映射,

    • 以下展示了MMU(Memory Management Unit,存储器管理单元)如何利用页表实现这样的功能

      • 页表基址寄存器(Page Table Base Register,PTBR)指向当前页表。
      • n

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值