操作系统存储管理之分页机制

粒度更细的内存划分

分段可以使用我们的内存利用率提高,分页可以进一步继续提高内存的利用率,的的粒度更细,页分为叶帧页面,叶帧是对物理内存划分的单位,简称。页面是对逻辑页面划分的单位,简称。分页机制首先也要解决划分和转换的问题,划分就是对物理内存和程序的划分,转换就是讲逻辑地址转化成真实的物理地址。

叶帧/帧(Frame)

我们将物理内存换分成大小相等帧,帧的大小为2^S,我们将物理地址的帧表示为一个二元组(f,o),f表示帧号,o表示帧内偏移量,因此我们要确定一个具体的物理地址只要将这几个数进行这样的计算:

物理地址 = f * 2^S + o

为什么帧的大小要控制为2^S呢,在计算机计数法中,我们知道计算机处理的都是二进制数,对二进制左移和右移可以快速的进行乘二和初二运算,这就是将择帧大小定为2^S(可能是64
512或者1024……)的原因

物理地址的表示

如果我们的一个物理地址为0000011000000110B(一个地址2字节),帧大小定为2^9,即S = 9,我们可以将地址的低S位表示为o(帧内偏移),剩下的高位表示为f(帧号),所以表示物理地址的二元组就为(3,6),验证一下:

物理地址 = 3 * 2^9 + 6 = 1542D

十进制1542D就等于二进制0000011000000110B

页面/页(Page)

进程的逻辑地址划分和物理地址的划分是一样的,这样划分以后,也就存在了页号和页内偏移的二元组(p, o),逻辑的转换:

逻辑地址 = p * 2^S + o

这个时候,我们寄存器中的地址就可以表示为这种形式了,表示方式和物理地址的方式一致

页到帧的映射

如果页为(p, o),对应的帧为(f, o),那么计算机在实际转换过程中是如何进行的呢?如果所示:

页表是一个数组,数组下标表示页号,数组值为帧号,用p在数组中找到f后,我们就找到了相应的物理地址了

页表

在CPU中有一个寄存器,存了当前进程页表所在的位置,这个寄存器叫页表基址寄存器(PTBR: Page Table Base Register),进程运行时,可以根据它找到页表所在位置。在页表中除了帧号还有一些标志位如

  • 存在位 表示一个页号是否有一个帧号对应,如果有就为1
  • 修改位 是否被修改
  • 引用位 是否访问过这个内存单元

页表的性能

在一个64位的系统中,假如我们的页大小为1K(2^10),那就有2^54个页,一个页表项为64位(8B),不算标志位,就需要2^57大小来存储页表,这个空间相当的大了,我们必须解决它,解决方式有两种,缓存间接访问

快表

快表(TLB)是在CPU里的一个缓冲区,它可以将访问过的页表项缓存在里面,下一次访问时,如果在快表中存在(命中),就可以直接得到物理地址了(CPU里的快表访问比内存中的页表访问快很多),如果没有命中,就在内存中的页表中去找,同时缓存到快表中,快表的访问次数越多,效率提升得就越高

多级页表

将页表的线性结构改成的结构,页表项中增加页表级数记录,如果分层k层,就需要k个记录,这样查询k+1后就可以找到相应的物理地址了,但是这样它的存储大小还是和线性的一样,在实际的运用中,可以根据存在位将一些不存在的下一级区域删除

Hash表

将页号通过Hash算法后,指向页表,页表是一个链表,这个链表的值就是一个Hash值,一个页号通过在页表中,也就是一个链表中搜索到和页号Hash值相同的页表项,通过该项确定帧号,通常在32位以上的操作系统使用

反置页表

上面介绍的页表是针对每个进程的,也就是页表是存储在各自的进程中,我们可以通过查询帧号,然后和偏移地址一起组成物理地址访问内存,而反置页表的就是在系统中只存在一个页表,也就是物理内存被分成了多少页,这个页表就有多少页,但是页表项的内容必须增加进程号,让CPU能够查询相应的页。主要实现是通过Hash(进程号和逻辑地址)映射值来进行查询。整个系统公用同一个页表,但是查找的成本增加,通过Hash算法可以快速命中

坚持原创分享,您的支持将鼓励我不断前行!