从01开始 从01开始
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理

    • 计算机组成原理-北大网课
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE

    • Ant
    • Maven
    • Log4j
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • Servlet
  • Spring
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC
  • SpringBoot
  • 学习网课的心得
  • 输入法
  • 节假日TodoList
  • 其他
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)

peterjxl

人生如逆旅,我亦是行人
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理

    • 计算机组成原理-北大网课
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE

    • Ant
    • Maven
    • Log4j
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • Servlet
  • Spring
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC
  • SpringBoot
  • 学习网课的心得
  • 输入法
  • 节假日TodoList
  • 其他
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)
  • 计算机历史

  • 数字电路

  • 计算机组成原理

  • 汇编语言

  • C语言

  • 数据结构

  • 操作系统

    • 我的操作系统学习笔记

    • 我的操作系统实验笔记

    • 操作系统网课-王道考研

      • 0_课程白嫖指南
      • 1_1_操作系统的概念(定义)、功能和目标
      • 1_2_操作系统的特征
      • 1_3_操作系统的发展与分类
      • 1_4_操作系统的运行机制与体系结构
      • 1_5_中断和异常
      • 2_1_1_进程的定义、组成、组织方式、特征
      • 2_1_6_系统调用
      • 2_1_2_进程的状态与转换
      • 2_1_3_进程控制
      • 2_1_4_进程通信
      • 2_1_5_线程概念和多线程模型
      • 2_2_1_处理机调度的概念、层次
      • 2_2_2_进程调度的时机、切换与过程、方式
      • 2_2_3_调度算法的评价指标
      • 2_2_4_FCFS、SJF、HRRN调度算法
      • 2_2_5_调度算法:时间片轮转、优先级、多级反馈队列
      • 2_3_1_进程同步、进程互斥
      • 2_3_2_进程互斥的软件实现方法
      • 2_3_3_进程互斥的硬件实现方法
      • 2_3_4_信号量机制
      • 2_3_5_用信号量实现进程互斥、同步、前驱关系
      • 2_3_6_生产者-消费者问题
      • 2_3_7_多生产者-多消费者问题
      • 2_3_8_吸烟者问题
      • 2_3_9_读者-写者问题
      • 2_3_10_哲学家进餐问题
      • 2_3_11_管程
      • 2_4_1_死锁的概念(1)
      • 2_4_2_死锁的处理策略—预防死锁
      • 2_4_3_死锁的处理策略—避免死锁
      • 2_4_4_死锁的处理策略—检测和解除
      • 3_1_1_内存的基础知识
      • 3_1_2_内存管理的概念
      • 3_1_3_覆盖与交换
      • 3_1_4_连续分配管理方式
      • 3_1_5_动态分区分配算法
      • 3_1_6_基本分页存储管理的基本概念
      • 3_1_7_基本地址变换机构
      • 3_1_8_具有快表的地址变换机构
      • 3_1_9_两级页表
        • 单级页表存在的问题
        • 两级页表的原理、地址结构
        • 如何实现地址转换
        • 解决页表常驻内存的问题
        • 需要特别注意的小细节
        • 小结
      • 43_3_1_10_基本分段存储管理方式
      • 3_1_11_段页式管理方式
      • 3_2_1_虚拟内存的基本概念
      • 3_2_2_请求分页管理方式
      • 3_2_3_页面置换算法
      • 3_2_4_页面分配策略
      • 4_1_1_初识文件管理
      • 4_1_2_文件的逻辑结构
      • 4_1_3_文件目录
      • 4_1_4_文件的物理结构(上)
      • 4_1_4_文件的物理结构(下)
      • 54_4_1_5_文件存储空间管理
      • 4_1_6_文件的基本操作
      • 4_1_7_文件共享
      • 4_1_8_文件保护
      • 4_1_9_文件系统的层次结构
      • 4_2_1_磁盘的结构
      • 4_2_2_磁盘调度算法
      • 4_2_3_减少磁盘延迟时间的方法
      • 4_2_4_磁盘的管理
      • 5_1.2_I-O控制器
      • 5_1.3_I-O控制方式
      • 65_5_1_1_I-O设备的概念和分类
      • 5_1_4_I-O软件层次结构
      • 5_1_5_I-O核心子系统
      • 5_1_6_假脱机技术
      • 5_1_7_设备的分配与回收
      • 5_1_8_缓冲区管理
    • 操作系统
  • Linux

  • 计算机网络

  • Git

  • 数据库

  • 计算机小知识

  • 编译原理

  • 名人堂

  • 计算机基础
  • 操作系统
  • 操作系统网课-王道考研
2023-05-15
目录

319_两级页表

# 3.1_9_两级页表

‍各位同学大家好,‍‍在这个小节中我们会介绍两级页表相关的一系列知识点,两级页表其实是为了解决单极页表当中存在的一些问题,所以我们会从单集页表存在的问题‍‍着手开始分析并且分析如何解决这些问题,由此引出两级页表机制。‍‍ 那么两级页表的原理、逻辑地址结构还有地址变化的过程,这是咱们之后会讲解的内容。‍‍最后我们还会强调几个两级页表问题,在考试当中有可能会作为考点的一个很重要的几个细节,‍‍我们会按照从上至下的顺序依次讲解。‍‍

​

‍

# 单级页表存在的问题

首先来看咱们之前介绍过的单级页表机制存在什么问题,假设一个计算机系统按照字节选址支持32位的逻辑地址,‍‍那么采用分页存储管理页面大小是4KB,页表项长度是4个字节,‍‍既然一个页面的大小是4KB,也就是2的12次方个字节,所以‍‍在这32位的逻辑地址当中,需要有12位来表示页内地址,然后剩余的20位才是表示页号

既然有20位表示页号,也就意味着一个用户进程最多有可能有2的20次方个页面,‍‍而我们知道每一个页面需要对应一个页表项,那么这么多的页面‍‍就需要的对应同等的2^20^次方个页表项,而每个页表项的大小是4个字节,‍‍所以总共就需要二的22次方个字节来存储进程的页表。‍‍这么多的字节总共就是2的10次方个页框,也就是1024个页框。‍‍

但是之前咱们讲过,‍‍为了实现通过页号查询对应的页表项这件事情,那么一般来说‍‍整个页表都是需要连续的存放在内存当中的,因此在这个系统当中‍‍一个进程光它的页表就有可能需要占用连续的1024个页框来存放,‍‍要为一个进程分配这么多的连续的内存空间,这显然是比较吃力的。‍‍并且这已经丧失了我们离散分配这种存储管理方式的最大的一个优点。‍‍所以这是单级页表存在的第一个很明显的缺陷问题。‍‍

​

‍

第二个问题,‍‍由之前我们介绍过的局部性原理,我们可以知道很多时候其实进程在一段时间内只需要访问某几个特定的页面,‍‍就可以正常的运行了。因此我们没有必要让进程的整个页表都常驻内存,我们只需要让‍‍进程此时会用到的那些页面对应的页表项在内存当中保存就可以了,‍‍所以这是单级页表存在的第二个问题。‍‍

‍

‍

那么从刚才的分析当中,我们知道‍‍单击页表存在两个明显的问题,第一个问题就是页表必须连续的存放,‍‍所以如果页表很大的话,那么光页表就需要占用连续的很多个页框,这和我们‍‍离散分配存储管理的这种思想其实是相悖的,所以我们要尝试解决这个问题。‍‍第二个问题就是‍‍我们没有必要让整个页表都常驻内内存,因为进程在一段时间内可能只需要访问某几个特定的页面就可以顺利的执行了,‍‍这是基于局部性原理得出的一个结论,

我们首先讨论第一个问题应该怎么解决。‍‍其实我们可以参考一下我们之前解决进程在内存当中必须连续存储的问题的时候‍‍提出的那种思路。‍‍

我们之前的做法其实很简单,就是把进程的地址空间进行分页,‍‍然后再为进程建立一张页表,用来记录它的各个页面之间的顺序,‍‍还有保存的位置,这些信息。

同样的思路,其实我们也可以用来解决一个页表必须存储连续占用多个页框的问题,‍‍我们可以把很长的页表进行分组,让每一个内存块刚好可以放入一个分组,‍‍比如说像之前那个例子当中,我们的页面一个页面可以存放1k个页表项,所以我们可以‍‍让每1k个连续的页表项为一组,然后这样的一组就可以刚好占满一个内存块,然后再把这些各个分组‍‍离散的分配到各个内存块当中。‍‍为了保证我们把这些分组离散的放到各个内存块之后,‍‍还能够知道这些分组之间的先后顺序,因此我们依然是像需要模仿之前的这种思路,‍‍为这些分组再建立一个页表,‍‍然后页表就称为页目录表,或者叫外层页表或者叫顶层页表。‍‍当然408的真题当中比较喜欢用的是页目录表这个名词,‍‍这个地方光看这些文字描述会比较抽象,

​

‍

‍

# 两级页表的原理、地址结构

我们直接结合图像来进行进一步的理解,‍‍还是沿着刚才的例子进行分析。‍‍32位的逻辑地址空间页表项大小为4b,页面大小为4KB,所以‍‍页内地址应该是占12位,其余的20位才是页号。‍‍所以如果我们采用的是单极页表结构的话,逻辑地址结构应该是这个样子。‍‍既然我们的页号有20位,就意味着在这个系统当中一个进程最多有可能会有2^20^个页面,‍‍相应的也会有2^20^个页表项。如果用10进制表示的话,这些页表项的编号应该是0到‍‍1048575,这其实就是2^20^-1这么一个数。‍‍

现在由于页表的长度过大,‍‍所以我们按照之前所说的那种思路,我们可以把这么大的一个长长的页表把它拆分成一个的小分组,‍‍每个小分组的大小可以让它刚好能够装入一个内存块,‍‍我们每个内存块或者说每个页面的大小是4KB,而页表项的大小是4b‍‍。所以一个内存块一个页面可以存放4k除以4,也就是1k个页表项,‍‍那么换算成十进制就应该是1024个页表项,因此我们可以把这么大的页表拆分成一个一个小分组,‍‍每一个分组的页表项有1024个,就像这个样子。‍‍另外我们可以给这些小页表进行编号,‍‍0号页表1号页表和一直到1024个页表,‍‍进行这样的拆分之后,最后总共就会形成1024个一个的小页表。

​

‍

‍

这个地方可以稍微注意一下的是,‍‍以前在大页表当中编号为1024的页表项,‍‍在进行拆分以后,应该是变成了第二个小页表当中的第一个页表项,‍‍所以可以看到页表项和页表项的块号是一样的,只不过页号就变为了从0开始,‍‍

​

‍

‍

‍

我们继续往下分析,再把大页表拆分成这样一个小页表之后,‍‍由于每一个小页表的大小都是4KB,因此每一个小页表都可以依次放到‍‍不同的内存块当中。‍‍所以为了记录这些小页表之间的相对顺序,还有它们在内存当中存放的块号位置,‍‍我们需要为这些小页表再进行再建立上一级的页表,‍‍而这级的页表就叫做页目录表或者叫顶级页表,外层页表,相应的‍‍这层的小页表,我们可以把它称为二级页表。‍‍

​

‍

从这个图当中也可以很直观的看到,‍‍页目录表其实是建立了二级页表的页号,还有二级页表‍‍在内存当中存放的块号之间的一个映射的关系。‍‍所以如果此时我们想要找到0号页表的话,那么我们可以通过页目录表‍‍就可以知道0号页表是存放在3号内存块里的,所以只需要在3号内存块这个地方来找0号页表就可以了。‍‍

在采用了这样的两级页表结构之后,逻辑地址的结构也需要发生相应的变化,‍‍我们可以把以前的20位的页号拆分成2个部分,第一个部分是10位的二进制用来表示一级页号,‍‍第二部分也是10位二进制用来表示2级页号,那10位的二进制大家会发现‍‍刚好是可以表示0~1023这么一个范围,所以用一级页号来表示这个范围是刚好的。‍‍相应的二级页号的这10个二进制位,就是用来表示2级页表当中的这些页号。‍‍

​

‍

‍

# 如何实现地址转换

接下来我们再结合这个例子来看一下我们应该怎么实现地址的变化,‍‍把逻辑地址这么一串东西转换成物理地址,并且最后的物理地址要用10进制表示。‍‍

那么要进行地址变化,我们要做第一件事情就是根据我们的地址结构,把逻辑地址拆分成三个部分,‍‍也就是一级页号,二级页号,还有页内偏移量这么三个部分。‍‍

第二步我们可以从PCB当中知道‍‍我们的页目录表在内存当中存放的位置到底是哪里,这样的话我们就可以根据一级页号来查询页目录表了,‍‍一级页号是0,从页表项当中我们可以知道‍‍0号的二级页表存放在内存块号为3号的地方,‍‍所以我们可以从这个位置读出二级的页表,然后开始用二级页号来‍‍再进行查询。‍‍

二级页号是一,‍‍通过页表项我们就可以知道,最终我们想要访问的地址应该是在4号内存块里的。‍‍所以接下来我们就可以根据最终要访问的内存块号和页内偏移量,‍‍得出我们最终的物理地址了。由于我们想要访问的是4号内存块,并且每个内存块的大小是4KB,也就是‍‍4096个字节,所以4号内存块的起始地址应该是4×4096,就等于16384。‍‍另外页内偏移量把它转换为10进制之后应该是1023,所以我们可以用内存块的起始地址,‍‍再加上页内偏移量的数字,就可以得到最终的物理地址17407了。‍‍

​

经过刚才的一系列分析,我们就解决了我们之前提出的第一个问题。‍‍当页表很大的时候,其实我们可以采用两级页表的这种结构,来解决页表必须连续的占用多个页框的问题。‍‍

‍

# 解决页表常驻内存的问题

接下来我们再来看一下第二个问题应该怎么解决。其实‍‍如果说不让整个页表常驻内存的话,那么我们可以在需要访问页面的时候,‍‍才把页面调入内存,其实这是咱们之后会介绍的虚拟存储技术。在之后的小节当中会有更详细的介绍,这只是‍‍先简单的提一下他的思想。‍‍

我们可以给每一个页表项增加一个标志位,用来表示‍‍这个页表相对应的页面到底有没有调入内存。‍‍如果说此时想要访问的页面暂时还没有调入内存的话,那么就会产生一个缺页中断。‍‍然后操作系统负责把我们想要访问的目标页面从外存调入内存
缺页中断肯定是我们在执行某一条指令,想要访问到某一个暂时还没有调入的页面的时候产生的,‍‍所以这个中断信号和当前执行的指令有关,因此这种中断应该是属于内中断,‍‍这个部分的内容咱们在之后的小节当中还会有更详细的介绍。‍‍

​

‍

‍

# 需要特别注意的小细节

接下来我们再来强调几个在考试当中需要特别注意的小细节。第一个,‍‍如果我们采用的是多级页表机构的话,那么‍‍各级页表的大小不能超过一个页面,这个限制的条件,我们在做题的时候应该怎么应用?

我们直接来看一个例子,‍‍假设某系统按字节编制采用40位逻辑地址结构,然后页面大小是4KB,页表项是4b‍‍,如果采用的是纯页式存储的话,需要采用几级页表,页内偏移量又是多少位呢?‍‍

我们首先最容易确定的应该是页内偏移量的位数,每个页面的大小是4KB,‍‍而这个系统是按字节编制的,所以页内偏移量应该占12位,‍‍而剩余的28位就应该是用来表示页号的。‍‍

另外由于每个页面的大小是4KB,而每个页表项是4b,所以一个页面可以存放‍‍二的10次方个页表项也就是1024个页表项。‍‍

由于采用多级页表的时候,各级页表的大小不能超过一个页面,所以说各级页表当中‍‍页表项最多不能超过2的10次方格,相应的各级页号所占的位数也不能超过10位

所以28位的页号,我们可以把它分成3个部分,1级页号占8位,2级页号,10位,3级页号,也占10位,‍‍相应的这样的话我们就需要再建立更高一级的页表,最终会形成三级页表的一种结构。‍‍三级页表的原理和两级页表的原理其实是一模一样的,这个地方就不再展开赘述。‍‍

这个地方假如说我们只是采用了两级页表的结构的话,那么低级的页号就会占18位,‍‍也就是说在页目录表当中最多有可能会有二的18次方个页表项,这么多的页表项‍‍显然是不能放在一个页面里的,所以这就违背了‍‍采用多级页表的时候,各级页表的大小不能超过一个页面这样的条件,因此‍‍如果我们只把它分成两级是不够的,‍‍这就是我们需要注意的第一个细节,很有可能作为考点在选择题,甚至是结合大题来进行考察。‍‍

​

‍

第二个我们需要注意的点是两级页表的访存次数的分析。‍‍

两级页表的访存次数分析(假设没有快表机构)

  • 第一次访存:访问内存中的页目录表
  • 第二次访存:访问内存中的二级页表
  • 第三次访存:访问目标内存单元

‍

假设我们没有采用快表机制的话,那么第一次访存应该是访问内存当中的页目录表,也就是顶级页表。‍‍第二次访存应该是访问内存当中的二级页表,‍‍第三次访存才是访问最终的目标内存单元,所以采用两级页表结构的话,‍‍我们要访问一个逻辑地址,需要进行三次访存。

那还记得我们分析的单级页表的访存次数问题吗?‍‍如果采用的是单级页表结构的话,那么第一次访存就是查询页表第二次访存,‍‍访问我们最终想要访问的内存单元,‍‍所以‍‍单级页表在访问一个逻辑地址的时候,只需要进行两次访存。‍‍因此两级页表虽然解决了我们之前提出的单极页表的那两大问题,‍‍但是这种内存空间的利用率的上升,付出的代价就是‍‍逻辑地址变换的时候需要进行更多一次的访存,‍‍这样的话就会导致我们要访问某一个逻辑地址的时候,需要花费更长的时间,‍‍所以这是2级页表相比于单级页表来说的一个很明显的缺点。‍‍如果我们继续分析3级页表4级页表‍‍结构当中的访存次数的话,会发现3级页表访问一个逻辑地址需要访存4次,4级页表‍‍需要缓存5次,5级页表需要缓存6次,所以其实有1个规律,如果是没有快表机构的话,那么n级页表‍‍在访问一个逻辑地址的时候,访存次数应该是n+1次,‍‍这就是我们需要注意的两个很重要的小细节。‍‍

‍

‍

‍

‍

# 小结

那么小节当中我们介绍了两级页表相关的知识点,我们从单极页表存在的两个问题出发,‍‍来依次探讨了这两个问题应该怎么解决,特别是第一个‍‍

采用了两级页表结构之后,我们就可以解决第一个问题,但是第二个问题的解决需要采用‍‍虚拟存储技术,咱们会在之后的小节进行更详细的讲解。‍‍在本节当中我们需要重点理解两级页表的逻辑地址结构,‍‍还需要注意页目录表、外层页表顶级页表这几个说法,不过在408当中最常用的是页目录表术语。‍‍

另外大家也需要理解采用了两级,页表之后如何实现逻辑地址到物理地址的转换,‍‍转换过程其实和咱们之前介绍的单极页表并没有太大的差异,‍‍无非就是还需要多查一级的页表而已,这个过程需要能够自己分析。‍‍

最后我们强调了两个我们需要注意的小细节,第一个小细节,多级页表当中各级页表的大小不能超过一个页面,‍‍所以说如果两级页表不够的话,那么我们可以进行更多的分级。‍‍第二个小细节,我们也需要自己能够分析多级页表的访存次数, n极页表访问一个逻辑地址是需要n+1次访存的。‍‍

另外大家还需要能够根据题目给出的逻辑地址、位数、页面大小、页表项大小,‍‍这几个条件来确定多级页表的逻辑地址结构,这些内容还需要大家结合课后习题来进行巩固和消化

​

在GitHub上编辑此页 (opens new window)
上次更新: 2023/5/16 10:03:43
3_1_8_具有快表的地址变换机构
43_3_1_10_基本分段存储管理方式

← 3_1_8_具有快表的地址变换机构 43_3_1_10_基本分段存储管理方式→

Theme by Vdoing | Copyright © 2022-2023 粤ICP备2022067627号-1 粤公网安备 44011302003646号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式