当允许进程增长大于内存时,页表也会变得非常大。我们如何组织页表和TLB以尽可能快地保存具有良好位置的代码的访问时间?例如,假设物理内存为512K,每页为1K,TLB大小为128.如果我们假设大多数进程为256K或更少,那么我们可以分配一个包含256个条目的固定大小的页表。现在在意外情况下,页表大于256个条目,我们应该如何组织它?您的设计对平均访问时间和程序的最大虚拟内存大小有何影响?
答案 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位偏移量)
我希望这能回答你的问题。实际实现需要根据许多约束进行设计选择。