如何使用倒置页表节省空间



如果我们使用倒排页表将虚拟地址映射到物理地址,为什么还要节省内存?例如,如果我们有两个进程都有 4 页,我们将在两个不同的表中有 8 个条目,指向从虚拟地址到物理地址:

Process 1:
[0] = 1
[1] = 5
[2] = 63
[3] = 0
Process 2:
[20] = 14
[21] = 55
[22] = 11
[25] = 9

如果我们使用倒置页表,我们只会有一个大表指向相反的方向。但在大小上它们相等。

2) Inverted page table
[0] = <p1 | 3>
[1] = <p1 | 0>
[5] = <p1 | 1>
[9] = <p2 | 25>
[11]= <p2 | 22>
[14]= <p2 | 20>
[55]= <p2 | 21>
[63]= <p1 | 2>

第一种情况下的页表是每个进程的数据结构。每个进程都有一个指向自己的页表的指针,当进程被调度时,这个指针被加载到%CR3寄存器中。当它与其他寄存器一起进行上下文切换时,它也会被保存。

但倒排哈希表是一种全局数据结构。使用此技术的操作系统将使用某种锁定机制,在给定时间点仅访问 1 个进程。(想象一下 2 个内核上的 2 个进程同时访问全局数据)。

假设每个进程 ram 为 4GB 和 4096 页大小,在第一种情况下,每个进程都有 4GB/4096 ,(其页表中的条目数 * 每个页表条目的大小),对于每个创建/分叉的进程,所有这些都会占用空间。用于将虚拟进程映射到物理进程的总内存是所有进程的页表大小的总和。这是更简单的方法,因为在每个上下文切换中,您只会更改一个指针,并不复杂。

在第二种情况下,您将拥有一个只有 4GB/4096 条目的表,因此节省了空间,但内存管理变得复杂,因为这是一个全局数据,您必须在每个条目中添加更多信息,告诉当前所有者如何(如您所显示的)等。MMU/OS 必须注意同步。

但是您给出的示例并不准确,在具有每个进程页表的真实系统上,可以访问整个地址,在您的情况下,进程 p1 有 4 页,而 p2 有不同的页面集。实际上,两个进程都可以访问相同的虚拟地址,映射到不同的物理帧。因此,每个表中的每个表都必须有 8 个条目。

页表必须位于一个块上(您可以像在数组中一样获得页面)。你从倒置表中得到 2 件事。

目录表越来越小,例如,得到的不是 2^20 的表大小和 2^

12 的偏移量,而是 2^10 的目录表大小。

然后,大多数页面将映射到磁盘中,而不是获取页表的 (2^20) * (2^2) 字节内存,并且只有在进程需要时才分配它。

在您的情况下,不是所有进程都有一个大小为 2^20 * 2^2 字节的页表,而是只有 2^10 * 2^2 字节用于目录表,另一个 2^

10 * 2^2 字节用于页表。 这是一个很大的区别,而不是 2^22 字节,你有 2^13。

我希望它很清楚。

倒排页表较小,因为它的大小取决于内存大小而不是虚拟地址空间大小。如果虚拟地址空间为 2^48,则每个进程可以有 2^36 个页表条目。

对于倒排页表,页表条目的数量仅取决于内存的大小。假设您有 4GB 的内存,那么您的倒排页表将有 2^32 - 2^12 = 2^20 个条目。这也适用于任何数量的进程。

最新更新