虚拟内存页表增长

时间:2015-08-28 22:46:16

标签: operating-system virtual-memory tlb

当允许进程增长大于内存时,页表也会变得非常大。我们如何组织页表和TLB以尽可能快地保存具有良好位置的代码的访问时间?例如,假设物理内存为512K,每页为1K,TLB大小为128.如果我们假设大多数进程为256K或更少,那么我们可以分配一个包含256个条目的固定大小的页表。现在在意外情况下,页表大于256个条目,我们应该如何组织它?您的设计对平均访问时间和程序的最大虚拟内存大小有何影响?

1 个答案:

答案 0 :(得分:0)

x86上使用的解决方案是"稀疏"页表,即没有一个完整的表来包含每个页面的映射。而是使用两级机制:

虚拟内存大4 GB。单个页面的大小为4 KB。因此,使用一级方法需要一个4 GB / 4 KB = 1024 * 1024条目表。如果一个条目消耗了4个字节,那么每个进程只需要4 MB来存储它的表。

使用a two level approach我们有一个页面目录,包含1024个条目,每个条目大小为4个字节(使其完全适合单个4 KB页面)。因此,该目录中的每个条目都管理4 GB / 1024 = 4 MB。如果(且仅当)应该将某些虚拟内存页面映射到4 MB范围内的物理内存,则该条目指向另一个结构的实例,页表 。它也包含1024个条目,因此每个条目只管理一个页面4 MB / 1024 = 4 KB

如果某个流程只需要一个页面来运行,那么使用单级方法我们需要4 MB来存储其虚拟内存配置。使用上述两级机制,我们需要4 KB用于页面目录,4 KB用于包含该单页面映射的页面表。因此,只有8 KB用于存储虚拟内存配置。

如果进程在运行时需要额外的内存,并且该内存位于不在其页表管理的4 MB范围内的(虚拟)地址,则需要提供第二个页表,从而增加用于存储另一个4 KB映射的内存。

使用这种两级方法稍微增加了不在TLB中的页面的访问时间,因为内存管理单元需要访问两个内存位置(页面目录,然后是相应的页面表)才能够计算物理地址

TLB不受此影响:它存储单个页面的映射。如何建立这些映射与其操作无关。

让我们将其应用于您在上面给出的示例配置: 单页大小为1 KB。如你所说,大多数进程的内存都会256 KB或更少。但是我们希望能够使用更多的虚拟内存。

如果我们选择让最后一个级别处理完整的256 KB,那么我们就可以了 256 KB / 1 KB = 256条目。假设32 bit架构,这反过来意味着我们可以让每个条目的大小为4 byte(以保存地址)。 256 entries * 4 Byte = 1 KB因此整整一页。好的。

为了能够处理比256 KB更多的虚拟内存,我们添加了另一个层。因为它很简单,我们让这个级别使用256个条目(4个字节)的表格,使这样的表格完全适合页面。

这为我们提供了256 * 256 KB(大约65 MB)的虚拟内存。然后,该系统中的虚拟地址将为26 bit长:

DDDDDDDDTTTTTTTTPPPPPPPPPP

D := Index to page directory, highest level.
     8 bit to be able to index 256 entries.
T := Index to page table, lower level.
     8 bit to be able to index 256 entries.
P := Offset inside page.
     10 bit to be able to address 1024 bytes.

使用少于256 KB的进程需要2 KB来管理其内存配置。每增加256 KB个虚拟内存需要添加另一个1 KB配置内存。

假设TLB可以容纳128个条目(这里你的问题有点不清楚),它需要128 * (16 + X - 10) bit,其中X是用于寻址物理内存的位数。 (虽然这取决于实际的实现。我在考虑每个条目16 bit来存储分页结构的索引+物理地址的高位,不计算10位偏移量)

我希望这能回答你的问题。实际实现需要根据许多约束进行设计选择。