1.写在前面

我在前面介绍了对应的虚拟机,以及一些虚拟机的的指令的模式,这节我们主要讲一下虚拟存储。

2.虚拟存储

我们知道了cache如何对程序中最近访问的代码和数据提供快速访问。同样,主存可以为通常由磁盘实现的辅助存储充当cache。这种技术被称为虚拟存储。从历史上看,提供虚拟存储的主要动机有两个:允许在多个程序之间高效安全地共享内存,例如云计算的多个虚拟机所需的内存,以及消除小而受限的主存容量对程序设计造成的影响。50年后,第一条变成主要设计动机。

当然,为了允许多个虚拟机共享内存,必须保护虚拟机免受其他虚拟机影响,确保程序只读写分配给它的那部分主存。主存只需存储众多虚拟机中活跃的部分,就像cache只存放一个程序的活跃部分一样。因此,局部性原理支持虚拟存储的cache,虚拟存储允许我们高效地共享处理器以及主存。

在编译虚拟机时,无法知道哪些虚拟机与其他虚拟机共享存储。事实上,共享存储的虚拟机在运行时会动态变化。由于这种动态的交互作用,我们希望将每个程序都编译到它自己的地址空间中,只有这个程序能访问的一系列存储位置。虚拟存储实现了将程序地址空间转换为物理地址。这种地址转换处理加强了各个程序地址空间之间的保护。

虚拟内存的第二个动机是允许单用户程序使用超出内存容量的内存。以前,如果一个程序对于存储器来说太大,程序员应该调整它。程序员将程序划分成很多端,并将这些段标记为互斥的。这些程序段在执行时由用户程序控制载入或换出,程序员确保程序在任何时候都不会访问未载入的程序段,并且载入的程序段不会超过内存的总容量。传统的程序段被组织为模块,每个模块都包含代码和数据。不同模块之间的过程调用将导致一个模块覆盖掉另一个模块。

可以想象,这种责任对程序员来说是很大的负担。虚拟存储的发明就是为了将程序员从这些困境中解脱出来,它自动管理由主存和辅助存储所代表的两级存储层次结构。

虽然虚拟存储和cache的工作原理相同,但不同的历史根源导致它们使用术语不同。虚拟机存储块被称为页,虚拟存储失效被称为缺页失效。在虚拟存储中,处理器产生一个虚拟地址,该地址通过软硬件转换为一个物理地址,物理地址可访问主存。

在这里插入图片描述

上图是分页的虚拟存储被映射到主存中。这个过程被称为地址映射或地址转换。如今,由虚拟存储控制的两级存储层次结构通常是个人移动设备中的DRAM和闪存,在服务器中的DRAM和磁盘。如果回到我们的图书馆类比,可以将虚拟地址视为书名,将物理地址视为图书馆中该书的位置,它可能是图书馆的索书号。

虚拟内存还通过重定位简化了执行时程序的载入。在用地址访问存储之前,重定位将程序使用的虚拟地址映射到不同的物理地址。重定位允许将程序载入主存中的任何位置。此外,现在所有的虚拟存储系统都将程序重定位成一组固定大小的块,从而不需要寻找连续内存块来放置程序,相反,操作系统只需要在主存中找到足够数量的页。

在虚拟存储中,地址被划分为虚拟页号和业内偏移

在这里插入图片描述

上图显示了虚拟页号到物理页号的转换。虽然RISC-V有64位地址,但其中的高16位未使用,因此要映射的地址有48位。假定物理内存容量为1TB或2^40字节,则需要40位地址。物理页号构成物理地址的高位部分。页内偏移不变,它构成物理地址的低位部分。页内偏移的位数决定页的大小。虚拟地址可寻址的页数和物理地址可寻址的页数可以不同。拥有比物理页更多数量的虚拟页是一种没有容量限制的虚拟存储的基础。

缺页失效的高成本是许多设计选择虚拟存储系统的原因。磁盘的缺页失效处理需要数百万个时钟周期。这种巨大的失效代价导致了设计虚拟存储系统时的几个关键决策:

  • 也应该满足大以分摊长访问时间。目前典型的页大小从4KiB到64KiB不等。支持32KiB和64KiB页的新型桌面和服务器正在研发,但是新的嵌入式系统正朝另一个方向发展,页大小为1KiB。
  • 能降低缺页失效率的组织结构很有吸引力。这里使用的主要技术是允许存储中的页以全相联方式放置。
  • 缺页失效可以由软件处理,因为与磁盘访问时间相比,这样的开销将很小。此外,软件可以用巧妙的算法来选择如何放置页面,只要失效率减少很少一部分就足以弥补算法的开销。
  • 写穿透策略对于虚拟存储不合适,因为写入时间过长。相反,虚拟存储系统采用写回策略。

2.1页的存放和查找

由于缺页失效的代价非常高,设计人员通过优化页的放置来降低缺页失效频率。如果允许一个虚拟页映射到任何一个物理也,那么在发生缺页失效时,操作系统可以选择任意一个页进行替换。例如,操作系统可以使用复杂的算法和复杂的数据结构来跟踪页面使用情况,来选择在较长一段时间内不会被用到的页。使用先进灵活的替换策略降低缺页失效率,并简化了全相联方式下页的放置。

全相联映射的困难在于项的定位,因为它可以在较高存储层次结构中的任何位置。全部进行检索是不切实际的。在虚拟存储系统中,我们使用一个索引主存的表来定位页;这个结构称为页表,它被存在主存中。页表使用虚拟地址中的页号作为索引,找到相应的物理页号。每个程序都有自己的页表,它将程序的虚拟地址空间映射到主存。在图书馆类比中,页表对应于书名和图书馆位置之间的映射。就像卡片目录可能包含学校中另一个图书馆中书的表项,而不仅仅是本地的分馆,我们将看到该页表也可能包含不在内存中的页的表项。为了表明页表在内存中的位置,硬件包含一个指向页表首地址的寄存器,我们称之为页表寄存器。现在假定也表存在存储器中一个固定的连续区域中。

2.2缺页失效

如果虚拟页的有效位为无效,则会发生缺页失效。操作系统获得控制。这种控制的转移通过例外机制完成,一旦操作系统得到控制,它必须在存储层次结构的下一级中找到该页,并确定请求的页放在主存中的什么位置。

虚拟地址本身并不会立即告诉我们该页在辅助存储中的位置。回到图书馆的类比,我们无法仅依靠书名来找到图书的具体位置。而是按目录查找,获得书在书架上的位置信息,比如说图书馆的索引书号。同样,在虚拟存储系统中,我们必须跟踪记录虚拟地址空间的每一页在辅助存储中的位置。

由于我们无法提前获知存储器中的某一页什么时候将被替换出去,因此操作系统通常会在创建进程时为所有页面在闪存或磁盘上创建空间。这个空间被称为交换区。那时,它也会创建一个数据结构来记录每个虚拟页在磁盘上的存储位置。该数据结构可以是页表的一部分,或者可以是具有与页表相同索引方式的辅助数据结构。如下图:

在这里插入图片描述

操作系统还会创建一个数据结构用于跟踪记录使用每个物理地址的是哪些进程和哪些虚拟地址。发生缺页失效时,如果内存中的所有页都正在使用,则操作系统必须选择一页进行替换。因为我们希望尽量减少缺页失效次数,所以大多数操作系统选择它们认为近期内不会使用的页进行替换。使用过去的信息预测未来,操作系统遵循最近最少使用LRU替换策略。操作系统查找最近最少使用的页,假定某一页在很长一段时间都没有被访问,那么该页再被访问的可能性比最近进程访问的页的可能性要小。被替换的页被写到辅助存储器中的交换去。如果还不是很明白,可以把操作系统看成另一个进程,而哪些控制内存的表在内存中,这看起来似乎有些矛盾。

2.3支持大虚拟地址空间的虚拟存储

对于4KiB大小的页,如果虚拟地址是48位,并采用单级页表,则页表有640亿个表项。由于RISC-V每个页表项中为8个字节,因此将虚拟地址映射到物理地址就需要0.5TiB存储空间!而且,如果计算机中同时有成百的进程同时运行,每个进程都有自己的页表。即使对于最大的系统,这样的大量的内存也无法承受。

一系列技术已经被用于减少页表所需的存储空间,以下五种技术从两个角度解决问题,一是减少存放页表所需的最大存储空间,而是减少用于存放页表的存储空间。

  1. 最简单的技术是保留界限寄存器,限制给定进程的页表大小。如果虚拟页号大于界限寄存器的值,那么表项将被添加到页表中。这种技术允许页表随着进程消耗空间的增多而增长。因此,只有当进程使用了许多虚拟页时,页表才会变得很大。这种技术要求地址空间只向一个方向扩展。

  2. 允许地址空间只朝一个方向增长并不够,因为大多数语言都需要两个大小可扩展的区域:一个区域容纳栈,另一个区域容纳堆。由于这种二元性,划分页表并使其可以从最高地址向下增长,也可以从弟弟地址向上增长就方便多了。这意味着将两个单独的页表和两个单独的界限寄存器。两个页表的使用将地址空间分成两段。地址的高位决定为该地址使用哪个段以及哪个页表。由于高位地址位指定段,因此每段的容量可以等于一半的地址空间。每个段界限寄存器指定当前段的大小,并以为页为单位增长。这种形式的段对应用程序是不可见的,但是对操作系统可见。这种方案的主要缺点是:当地址空间以稀疏方式而不是连续方式被访问时,它不能很好的工作。

  3. 另外一种减少页表容量的方法是对虚拟地址应用哈希函数,以使页表容量等于主存中物理也的数量。这种结构称为反向页表。当然,使用反向页表的查找过程稍微复杂一些,因为我们不能只通过索引来访问页表。

  4. 为减少页表占用的实际主存,大多数现代系统还允许将页表再分页。虽然这听起来很复杂,但是它的工作原理与虚拟存储相同,即允许将页表保存在虚拟地址空间中。另外,还必须避免一些小但很关键的问题,比如无止境的缺页失效。如何克服这些问题需要描述得很详细,并且这些问题一般对机器的依赖性很高。简而言之,为了解决这些问题,可以将所有页表放置在操作系统的地址空间中,并至少将操作系统的一些页表放置在物理地址空间中且总是存在于主存而不出现在二级存储中。

  5. 多级页表也可以用来减少页表存储的总量,这是RISC-V为减少地址转换占用的内存锁采用的解决方案。

    在这里插入图片描述

    从48位虚拟地址到4KiB页的40位物理地址的四级地址转换。首先使用地址的最高几位查看第0级页表表项指示的页表,依次类推。因此,第0级页表将虚拟地址映射到512GiB区域。第1级页表又将虚拟地址映射到1GiB区域。再下一级页表将其映射到2MiB区域。最后一级页表将虚拟地址映射到4KiB大小的内存页。该方案允许以稀疏的方式访问地址空间,而不必分配整个页表。这种方案对于非常大的地址空间和需要非连续地址分配的软件系统特别有用。多级页表的主要缺点是地址转换过程复杂。

3.写在最后

本篇博客主要简单的介绍虚拟存储,虚拟存储的页的存放和查找、以及缺页失效。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐