多级页表如何节省内存空间?

Posted

技术标签:

【中文标题】多级页表如何节省内存空间?【英文标题】:How does multi-level page table save memory space? 【发布时间】:2015-06-10 15:05:09 【问题描述】:

我想了解多级页表如何节省内存。据我了解,多级页表总共比单级页表消耗更多的内存。

示例:考虑一个页面大小为 64KB 和 32 位处理器的内存系统。页表中的每个条目都是 4 个字节。

单级页表:需要 16 (2^16 = 64KB) 位来表示页偏移。所以其余 16 位用于索引页表。所以

*页表大小 = 2^16(页数)* 4 字节(每个页表条目的大小)= 2^18 字节*

多级页表:在两级页表的情况下,让我们使用前 10 个最高有效位来索引到第一级页表。接下来的 10 位索引到二级页表中,该页表具有页号到帧号的映射。其余 12 位代表页面偏移量。

二级页表的大小 = 2^10(条目数)* 4 字节(每个条目的大小)= 4 KB

所有二级页表的总大小 = 2^10(二级页表的数量)* 4KB(每个二级页表的大小)= 4 MB

一级页表大小 = 2^10(# of entries) * (10/8) Bytes (Size of each entry) = 1.25 KB

存储一级和二级页表所需的总内存 = 4 MB + 1.25 KB

所以我们需要更多的内存来存储多级页表。

如果是这样,

【问题讨论】:

所有页表条目不必同时存在于内存中。只是***字典,其余的可以交换到磁盘并在需要时加载和使用(如果有的话)。所以节省(在我看来)是因为页面映射占用了适量的内存 计算一级页表大小时为什么要10/8? 【参考方案1】:
    在单级页表中,您需要整个表才能访问少量数据(更少的内存引用)。即 2^20 个页面,每个 PTE 占用 4 个字节。

访问任何数据所需的空间为 2^20 * 4bytes = 4MB

    分页页面是多级分页。在多级分页中更具体,您可以在多级组织的帮助下确定您的数据存在于2^20页中的哪个特定页面,并选择它。因此,在您运行该进程时,您只需要将特定页面保存在内存中即可。

在您讨论的 2 级情况下,您需要 1 级页表,然后需要 2 个 ^ 10 个页表中的 1 个在第二级。 所以, 第一级大小 = 2^10 * 4bytes = 4KB 第二级我们只需要 2^10 个页表中的 1 个 = 所以大小是 2^10 * 4bytes = 4KB

现在所需的总大小为:4KB + 4KB = 8KB。

最终比较是 4MB 与 8KB。

【讨论】:

很好解释。我想知道第 2 级页表的内容是什么。我知道,第 1 级的内容是帧号和一些位(脏、修改等)。 你能告诉我为什么 offset 在这里被认为是 12 吗?给定 64K 大小,偏移量不应该是 16 位吗?因此它只有 16 位用于页码分配。如果我们将它们平均分为两页。那么第一页的大小将为 2^8 * 4 字节,第二页的大小相同。那么总数将是 2* (2^8 * 4) = 2048 字节,与 2^16 * 4 字节相比要少得多。 @user3604958 页面大小 = 4KB,12 位偏移用于访问 4KB 地址范围内的特定地址。 4KB = 2^12,所以我们只需要 12 位的偏移量 @IbrahimAmer 但问题的作者指出,在他的案例中,页面大小为 64KB。为什么我们将其更改为 4KB?【参考方案2】:

这是多级页表的主要优点:

首先,将页表分割成页面大小的单元;那么,如果一整页页表条目 (PTE) 无效,则根本不分配该页表页。

Source.(第 20.3 节)

因此,页表所需的内存量不是由地址空间的大小决定的,而是由进程正在使用的内存量决定的。

此外,如果物理内存已满,页表条目的页面本身可以被分页 - 只有页面目录需要始终存在于内存中。

【讨论】:

我想知道第 2 级页表的内容是什么。我知道,第 1 级的内容是帧号和一些位(脏、修改等)。【参考方案3】:

要添加到Sai's answer,这里确实必须强调一个想法:您不需要将整个页表加载到主内存中 - 只需将您带到您想去的地方即可时间>。这弥补了您的正确直觉,即多级页表至少需要与单级页表一样多的容量(毕竟,无论表样式如何,您都需要存储所有虚拟地址的映射)。

还需要注意的是,多级分页实际上出现是因为想要应用上述原则(而不是相反,即应用该原则是因为您想使用多级分页)。单级表的条目本身存储在页中,在单级模型中,这些页可能会填满一大块内存;这样,您只需要基地址来索引您的表。但是,现在尝试拉出您不需要的条目页面:作为自然结果,我们需要一种方法来仍然能够引用所有条目页面,即使它们不再作为一大块。因此,出现了一个***页表,我们就有了多级分页。

现在只需将我们提取的页面写入磁盘,然后仅检索它们以供以后使用。这样,如果程序真的只需要一个最终级页表条目,我们将整个 4 MB 条目存储到磁盘中,除了我们实际需要的 4 kB + 4 kB。节省了很多 RAM。

【讨论】:

【参考方案4】:

由于 Intel 领域的内存结构,主要需要多级表。

假设你有一个 32 位系统,你划分地址空间,上半部分留给系统,下半部分留给用户地址。

通过这样的划分,每个用户页表中需要 2GB 的连续页表条目才能到达系统地址。

旧的 VAX 以一个简单的方法来解决这个问题。它将 4GB 地址空间划分为 4 个区域(2 个用户、1 个系统、1 个不可用)。三个可用区域都有自己的页表。

每个区域都有自己的页表。因为有一个专用的系统地址空间,所以用户页表可以是虚拟地址,因此它们不需要连续的内存。

地址转换的第一阶段是查看高 2 个地址位来选择要使用的页表。

Intel-land 没有单独的页表,而是分解了页表。这减少了(1)表需要连续内存的问题; (2) 要求页表跨越整个地址空间; (3) 允许定义一个可以被所有进程共享的内核地址。

【讨论】:

计算一级页表大小时为什么要10/8?

以上是关于多级页表如何节省内存空间?的主要内容,如果未能解决你的问题,请参考以下文章

虚拟内存与进程地址空间

操作系统多级页表与快表--12

Linux进程概念——下验证进程地址空间的基本排布 | 理解进程地址空间 | 进程地址空间如何映射至物理内存(页表的引出) | 为什么要存在进程地址空间 | Linux2.6内核进程调度队列

Linux进程概念——下验证进程地址空间的基本排布 | 理解进程地址空间 | 进程地址空间如何映射至物理内存(页表的引出) | 为什么要存在进程地址空间 | Linux2.6内核进程调度队列

Linux进程概念——下验证进程地址空间的基本排布 | 理解进程地址空间 | 进程地址空间如何映射至物理内存(页表的引出) | 为什么要存在进程地址空间 | Linux2.6内核进程调度队列

Linux 虚拟内存机制