【OS操作系统】Operating System 第四章:非连续内容分配

OS操作系统系列文章目录

【OS操作系统】Operating System 第一章:操作系统的概述
【OS操作系统】Operating System 第二章:启动、中断、异常和系统调用
【OS操作系统】Operating System 第三章:连续内存分配
【OS操作系统】Operating System 第四章:非连续内容分配
【OS操作系统】Operating System 第五章:虚存技术
【OS操作系统】Operating System 第六章:页面置换算法
【OS操作系统】Operating System 第七章:进程与线程
【OS操作系统】Operating System 第八章:处理机调度
【OS操作系统】Operating System 第九章:同步互斥问题
【OS操作系统】Operating System 第十章:信号量与管程
【OS操作系统】Operating System 第十一章:死锁与进程通信
【OS操作系统】Operating System 第十二章:文件系统



第四章:非连续内容分配

非连续内存分配的必要性

  • 连续内存分配的缺点:

    • 分配给一个程序的物理内存是连续的;
    • 内存利用率低;
    • 有外碎片、内碎片的问题;
  • 非连续内存分配的优点:

    • 一个程序的物理地址空间是非连续的;
    • 更好地利用和管理内存;
    • 允许共享代码与数据(共享库等);
    • 支持动态加载和动态链接;
  • 非连续内存分配的缺点:

    • 软件方案(开销太大);
    • 硬件方案(开销较小):
      • 分段;
      • 分页;

非连续内存的分配

分段(Segmentation)

  • 逻辑地址空间是连续的,物理地址空间是离散的,使用映射机制进行关联;

在这里插入图片描述

  • 逻辑地址由有序对组成,表现为二维地址,<段号s,偏移d>;

  • 其中,段号指的是物理地址空间,一个内存块;

  • 段表:由OS进行维护;

    • 里面每一个条目都有段基地址和段界限;
    • 段基地址:包含该段在内存中的起始物理地址;
    • 段界限:指定了该段的长度;

  • 分段的寻址方案
    • 程序访问,CPU给出逻辑地址;
    • 根据逻辑地址的段号,在OS维护的段表中,找到对应的起始物理地址;
    • 并比较段表给出的段界限和逻辑地址的偏移量;
    • 若偏移合法,这得到物理地址,即段表中的起始地址 + 二元组中的偏移地址;

在这里插入图片描述

分页(Paging)

  • 地址空间
    • 帧:将物理内存空间划分为固定大小的帧;
    • 页:将逻辑地址空间划分为相同大小的页;
    • 帧页的大小为2的幂次方;
    • 建立方案:转换逻辑地址为物理地址(pages to frams)
      • 页表(page table);
      • MMU、TLB(快表);

  • 物理地址空间:帧

    分页和分段的最大区别:帧的大小是固定的,段的大小是不定的;

    内存的物理地址表示为一个二元组(f, o),即(帧号, 帧内偏移量);

    • 帧号:共有F位二进制,表示物理地址空间有 2 F 2^F 2F个帧;
    • 帧内偏移量:共有S位二进制,表示每帧的大小为 2 S 2^S 2S​​​个字节;
    • 物理地址: 2 S ∗ f + o 2^S * f + o 2Sf+o

    在这里插入图片描述

  • 实例:
    在这里插入图片描述

  • 逻辑地址空间:页

    页号的作用就是通过二元组得到一个逻辑地址;
    而页号与帧号不是相等的;
    但是它们的偏移量是相等;

    内存的逻辑地址页表示为一个二元组(p, o),即(页号, 页内偏移量);

    • 页号:共有P位二进制,表示逻辑地址空间有 2 P 2^P 2P个页;
    • 页内偏移量:共有S位二进制,表示每页的大小为 2 S 2^S 2S​​个字节;
    • 虚拟地址: 2 S ∗ p + o 2^S * p + o 2Sp+o

  • 分页寻址方案:

    OS维护了一张页表,页表保存了逻辑地址和物理地址之间的映射关系;
    页表实际上可以认为是一个哈希表,index是页号,value是帧号;

    • 寻址过程:
      • 根据逻辑地址计算得到一个页号;
      • 根据页号,在页表中寻找到对应的帧号;
      • 根据帧号和偏移量,计算得到物理地址;
    • 特点:
      • 逻辑地址空间应当大于物理地址空间;
      • 页是连续的虚拟内存;
      • 帧是非连续的物理内存(有助于减少碎片的产生);
      • 不是所有的页都有对应的帧;

    在这里插入图片描述

页表和快表

  • 页表概述:

    每个运行的程序都有一个页表

    • 属于程序运行状态,会动态变化;
    • PTBR:页表基址寄存器;

  • 页表的每个表项都存储了特殊标志位:
    • dirty bit;
    • resident bit(0:对应的帧在内存中不存在;1:存在);
    • clock/reference bit;

在这里插入图片描述

  • 实例:
    • 逻辑地址(4,0),页号4对应的二进制是100,它的位置对应着flags;
      • 根据上图,可知它的dirty bit是1,resident bit是0,clock/reference是0;
      • 因此可以知道逻辑地址(4,0)在物理地址中实际是不存在的。如果CPU访问这个逻辑地址会抛出一个内存访问异常;
    • 逻辑地址(3,1034),页号3对应的二进制是011,它的位置(也就是页号的位置)对应着flags;
      • 根据上图,可知它的dirty bit是0,resident bit是1,clock/reference是1;
      • 因此可以知道逻辑地址(3,1034)在物理地址中存在;
      • 根据页表,页号3对应的页帧号是4,再加上它们的偏移量相等,所以逻辑地址(3,1034)对应的物理地址是(4,1023);

在这里插入图片描述

  • 分页机制的性能问题
    • 访问一个内存单元需要2次内存访问:
      • 一次用于获取页表项;
      • 一次用于访问数据;
    • 页表可能会非常大(约为 2 页 号 位 数 2^{页号位数} 2);
    • 每一个运行的程序都需要一个页表;
  • 解决办法:
    • 缓存(caching);
    • 间接访问(indirection);

转换后备缓冲区(快表TLB)

使用缓存的方法,优化分页表的时间开销问题;

  • Translation Look-aside Buffer(TLB)是CPU的MMU保存的一段缓存,这段缓存保存的内容 是页表的一部分,其内容是那些需要经常访问到的部分页表,其余不常用的页表内容仍保存在内存中;

  • 缓存近期访问的页帧转换表项:
    • TLB使用关联内存实现,具备快速访问性能;
    • 如果TLB命中,物理页可以很快被获取;
    • 如果TLB未命中,对应的表现被更新到TLB中(x86的CPU由硬件实现,其它的可能是由操作系统实现的);

在这里插入图片描述

二级页表和多级页表

  • 通过多级页表解决优化页表造成的空间开销问题:
    • 虽然增加了内存访问次数和开销,但是节省了保存页表的空间;
    • 相当于通过时间代价换取空间的优化,同时通过快表TLB也可以减少时间的消耗;

二级页表

  • 在逻辑地址中,页号被分为两个部分,分别是p1p2,其中一级页号对应着一级页表,二级页号对应着二级页表(二级页表不止一个);
  • 通过p1可以在一级页表中获取到对应二级页表的起始地址,该起始地址加上二级页号的地址值,可以在二级页表中获取到物理地址的帧号,并最后在偏移量的计算下,获得实际的物理地址;
  • 这个方法节约了一定的空间:
    • 在一级页表中,如果resident bit = 0,可以使得在二级页表中不再存储相关的index
    • 如果只有一张页表的话,这些没必要的index就要保留下来;

在这里插入图片描述

多级页表

  • 通过将页号分为k个部分,实现多级的间接页表,相当于建立了一棵页表树;
  • 例如64位系统,采用了5级页表;

在这里插入图片描述

反向页表

  • 传统页表的缺点:
    • 对于大地址空间,前向映射页表变得繁琐,如64位系统采用5级页表;
    • 逻辑地址空间的增长速度远快于物理地址空间,所有采用反向页表,用index表示物理地址,value表示逻辑地址,则该页表将会远小于传统页表的大小;

  • 反向页表:
    • 为了解决大地址空间的问题,希望通过物理地址的帧号获取逻辑地址的页号,而建立反向页表;
    • 反向页表建立后,只需要存在一张即可;
    • 存在的问题:映射关系的建立比较困难;

基于页寄存器(Page Registers)的实现方案


在这里插入图片描述

  • 页表中,index存储了帧号,value存储了标志位和页号;
    这样存储使得表的大小与物理内存大小相关,与逻辑地址内存关联性减少;

  • 反向页表中的表现都有一个关联的帧号和寄存器,寄存器内容:
    • redident bit:此帧是否占用;
    • occupier:对应的页号p;
    • protection bit:保护位;

  • 实例:
    • 物理内存大小:4k * 4KB = 16MB
    • 页面大小:4096 bytes = 4KB
    • 页帧数:4096 = 4k
    • 页寄存器使用空间(假设 8 bytes / register):4096 * 8 bytes = 32 KB
    • 页寄存器的开销:32 KB / 16 MB = 0.2%
    • 虚拟内存大小:任意;

  • 优势:
    • 转换表的大小相当于物理内存来说很小;
    • 抓换表的大小跟逻辑地址空间的大小无关;
  • 缺点:
    • 需要的信息被对调,即根据帧号找到页号;

基于关联内存(Associative Memory)的实现方案

  • 页寄存器的硬件设计复杂,容量不大,需要放在CPU中;

  • 解决方案:

    • 如果帧数较少,页寄存器可以放置在关联内存中;
    • 在关联内存中查找逻辑页号:
      • 成功:帧号被提取;
      • 失败:页错误异常(page fault);
    • 限制因素:
      • 大量的关联内存非常昂贵,难以在单个时钟周期内完成,耗电;

基于哈希的实现方案

  • 当物理内存特别大的时候,反向页表也很大,访问一个地址可能需要遍历整个表(因为是按照物理地址建立的,需要挨个访问);
  • 由于访问查找的比对是根据页号,而index是页帧号(ppn),所以只能从第一个页帧号开始,一个一个做比对(PID是当前进程的标识),速度较慢

在这里插入图片描述

  • 解决方案:基于哈希的反向页表

在这里插入图片描述

  • 上图中,vpn是页号,ppn是帧号,offset是偏移量,pid是标识号;
  • 在程序进行访问时,CPU给出逻辑地址,为了防止哈希冲突,并给出了当前进程的PID作为标识,以确保找到正确的帧号;
  • 将页号通过哈希计算(使用硬件加速),得到一个帧号,即反向页表的index,通过帧号,找到对应的表项;
  • 核对表现中的PID号是否与进程的PID号一致;
    • 如果一致,则当前帧号为正确的帧号;
    • 如果不一致,说明这里存在哈希冲突,则在表项中,寻找NEXT提供的下一个帧号;
      通过该帧号,重复上述操作,直到PID一致为止;
  • 在有帧号和偏移量的情况下,便可以计算出对应的物理地址;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值