虚拟内存的思想:每个进程都拥有自己的虚拟地址空间,这个空间被分割成多个块,每个块被称为一个页或者页面,每一页有连续的地址范围。这些也被映射到物理内存,但并不是所有的页面都在内存中,才能运行程序的,当程序引用到一部分在物理内存中地址空间时,有硬件执行必要的映射,当程序引用到一部分不在物理内存中的地址空间的时候,由操作系统负责将缺失的部分装入到内存并重新执行失败的指令。
加速分页过程
在任何分页系统中,需要考虑以下两个问题:
1)虚拟地址到物理地址的映射必须非常快。
2)如果虚拟地址空间很大,页表也会非常大。
第一个问题是由于每次访问内存的,都需要进行虚拟地址到物理地址的映射。
所有的指令最终都来自于内存,而且很多指令也会访问内存中的操作数,因此,每条指令进行一两次或者更多页表访问是必要的。
转换检测缓冲区:
微计算机设置一个小型的设备,将虚拟地址直接映射到物理地址,而不必访问页表,这种设备被称为转换检测缓冲区(TLB),有时也成为相联存储器,他通常在MMU中,包含少量的表项,最多不超过64个,每个表项记录了一个页面相关信息,包括虚拟页号,页面的修改位,保护码,和所对应的物理页框,除了虚拟页号,这些域与页表中的域一一对应。
TLB是如何让工作的?
将一个虚拟地址放入MMU进行转换的时候,硬件首先通过将该虚拟页号与TLB中所有表项同时进行匹配,判断虚拟页面是否在其中,要是在并且进行访问位并不太违反保护位,则将页框号直接从TLB中取出。而不必访问页表,如果虚拟页面号确实在TLB中,但是指令试图在一个只读页面上进行写操作,则会产生一个保护错误,就像对页表进行非法访问一样。
当虚拟页号不在TLB中的时候,如果MMU检测到内有有效位匹配的时候就会进行正常的也表查询,接着从TLB中淘汰一个表项,然后用找到的页表项代替他,这样,如果这一页表很快再次被访问,第二次访问TLB时自然将会命中,而不是不命中,当一个表项被清除出TLB时,将修改复制到内存中的页表项,而除了访问位,其他值不变。当页表项中从页表装入到TLB中时,所有的值就都来自内存。
软件TLB管理?
到目前为止,已经开发了多种不同的策略来改善使用软件TLB管理机器性能。一种是有时候操作系统能用“直觉”指出哪些页面下一步可能会被用到,并预先装载到TLB中,例如:当一个进程发送一条消息给同一台机器上的服务器进程,很可能服务器进程将不得不立即运行,了解到这一点,当执行send的时候,系统也可能找到服务器进程代码页,数据页以及堆栈页。并有可能导致TLB失效前把他们装载到TLB中。
当使用软件TLB管理时,一个基本的要求是要理解两种不同的TLB失效区别在哪里,当一个页面访问在内存中,而不在TLB的时候,将产生软失效,那此时所要做的就是更新一下TLB,不需要产生磁盘IO,当页面本身不在磁盘中的时候,将产生硬失效,此时需要一次磁盘存取以装入该页面,这个过程大概需要几毫秒。硬失效的处理时间往往是软失效的百万倍。
针对大内存的页面?
多级页表
32位的虚拟地址被划分成10位的PT1域、10位的PT2域,12位的Offset域,因为偏移量是12位,所以页面长度是4KB,共有2的20次方页面。
引入多级页表的原因是:避免将所有页表一直保存在内存中,特别是不需要的页表就不应该保留。
倒排页表:
倒排页表是解决64位机器虚拟内存的组织问题的一种新技术。
在设计中,每一个页框有一个表项,而不是每一个虚拟页面有一个表项,例如:对于64位虚拟地址,4KB的页面,1GB的RAM,一个倒排页表只需要记录262144个页表项,表项记录那一个(进程,虚拟页面)对定位于该页框,虽然倒排页表节省了大量的空间,但它还有严重的不足,从虚拟地址到物理地址的转换变的困难,当进程n访问虚拟页面的p时候,硬件不载通过把p当做指向页表的一个索引来查找物理页框,他必须查找整个倒排页表,来查找表项(n,p),此外,该搜索的必须对每一个内存访问操作都要执行一次,而不仅仅是缺页中断中执行,每一次访问操作都要查找256k的表。
为了提高查找速率,使用TLB,如果TLB能够记录所有频繁使用的页面,地址转换就可能变的像通常的页表一样快,但是,当发生TLB失效的时候,需要软件搜索整个倒排页表,一个可行的实现该搜索的方法是建立一张散列表,用虚拟内存散列,当前所有在内存中的具有相同的散列值的虚拟页面被连接在一起,如果散列表中的槽数和机器中物理页面一样多的话,散列表中的冲突链的平均长度将会是1个表项,这将会大大提高映射速度。一旦页框号被找到,新的(虚拟页号,物理页框)对就会被转载到TLB。