操作系统(九) -- 多级页表与快表

版权声明:若未特别声明,文章可随意转载,但是请注明出处~~ 文章若有侵权请在下方评论,博主看到后马上删除!! https://blog.csdn.net/williamgavin/article/details/83240402

单级页表的缺点

前面说了为了提高内存的利用率,内存是分页管理的,并且有一个页表用来存储页号与页框的对应关系。这个思想理论上是没有问题的,但是实际使用的时候就不行了,为什么?

为了更好的提高内存的利用率,每一页就应该做得足够小,但是每一页都要在页表里面有一项与页框对应,也就是说页数越多页表也就会越大,页表如果很大的话就会对内存造成浪费,因为存放页表的这部分你内存是不能给程序使用的,并且一直存放在该进程的PCB里面。那么究竟会造成多大的浪费?假设页面尺寸为4K,地址是32位,那么就有220个页面,页表里面就有220个页表项,如果每个页表项是4个字节,2^20个就是4M;系统并发十个进程,需要40M内存。如果并发一百个就是400M内存,这无疑是一个很大的开销。

但是实际上大部分的逻辑地址根本不会用到。为什么?如果你跑一个小程序,可能只需要几M或者几十M,也就是说页表里面用到的项只占2^20的很小一部分,那么能不能把不需要的那些项给屏蔽掉呢,也就是不存储那些项。

多级页表的提出

第一种尝试:页表里面只存放用到的页

比如一个程序用到了第1,3,5,6页,那么页表里面只需要存储这四页对应的页框号,但是这样的话页表里面的项就不连续了,这样找某一页对应的页框就不能直接使用偏移量的形式了。比较好的方法是折半查找(因为页号是有顺序的)。但是即便使用折半查找耗费的时间也会比使用偏移量大很多倍。比如如果一个表项有210个,时间复杂度log(210)=10,也就是需要10次,而如果使用偏移量就只需要一次就好了。所以页表里面的页号必须是连续的。

第二种尝试:多级页表,页目录表+页表

一个逻辑地址用10bits的页目录号+10bits的页号+12bits的偏移组成。页目录表的每一项对应一个页表,然后再根据页表找到对应的页。这种思想就类似与书本,目录的地方有一个章目录(页目录表)和节目录(页表),如果要查找某一节的内容首先找到这一章的地方,然后再查具体的某一节。我如果要找第五章的第4节,那么前面四章都不用看,直接找第五章就行了,这样除了第五章之外的页号对应的页框号的就不用存了。能节省大量内存;并且保证了章目录和节目录都是连续的,这就意味着可以使用偏移量的形式查找对应的章节。如下图:

在这里插入图片描述

多级页表的缺点

但是这种方式也存在一个问题,每一次访问的时候都要根据章目录找到页目录再找到具体的页。也就是需要访问三次内存;cpu每一条指令执行的时间其实大部分都是浪费在访问内存上,cpu的执行速度是非常快的,比如访问内存的时间几乎可以忽略了;换言之,两级页表的形式虽然提高了控件效率,但是在时间上其实是变成了原来的3倍的;这还只是两级页表,如果是4级或者5级的,因为电脑不是32位的啊,现在基本上都是64位的了。

相连快速存储TLB(快表)

在CPU与内存访问之间加一层TLB,TLB是一组寄存器,用来存放最近使用过的页对应的页框号;这样如果CPU需要访问某一页首先在TLB里面找,如果TLB里面有就不用访问内存了,因为TLB是寄存器,cpu访问寄存器的速度远大于对内存的访问速度。这样就可以提升时间性能了。可以看到提升时间性能最主要的因素就是可以在TLB里面直接找到该页对应的页框号。那么如何提升命中率的,首先TLB肯定是越大越好,但是TLB材料很贵,不会做得很大。TLB的大小大概是[64,1024]。为什么TLB里面存放这么少的项就能实现“近似访存1次”?因为程序的局部性原理。程序的局部性原理在用户程序里面对应的就是循环。TLB也被称为快表。

小结

总结一下:为了提高内存的空间性能,提出了多级页表的概念;但是提到空间性能是以浪费时间性能为基础的,因此为了补充损失的时间性能,提出了快表(即TLB)的概念,快表利用的是程序的局部性原理。

参考资料

哈工大李志军操作系统

猜你喜欢

转载自blog.csdn.net/williamgavin/article/details/83240402