是什么让指向第 table 页条目的指针数组比拥有第 table 页条目数组更好?

What makes having an array of pointers to page table entries better than having an array of page table entries?

这里 this lecture 讨论了页面 table 的一些极端实现以及一些合理的实现。

一种极端情况是分配一个平面数组,将每个可能的虚拟地址映射到物理地址。

19:19 分钟(给定的 link 开始),讲师说他正在谈论指向 PTE 的平面指针数组。然后提到他本可以做一些更愚蠢的事情,那就是使用一组实际页面 table 条目。

为什么拥有一个指向 PTE 的指针数组比拥有一个实际的 PTE 数组更好?

他说的是32位系统,地址是4字节,但是PTE也是4字节。

指针数组不是更浪费吗,因为它会占用 space 的两倍(指针为 4 个字节,PTE 为 4 个字节)?

此外,我认为分配大量分布在物理内存中的 PTE 会导致碎片化并且难以管理,而不是仅创建一个 PTE 数组,后者将是一块内存不需要太多的管理。

为什么指针数组会更好?

遍历页表以查找翻译时会产生开销。时不时地会有一篇新论文发表,解释它们的实施是如何优越的。有人建议 hashing the page tables。建议大家不要想太多,了解遍历页表的原理,简单的实现就可以掌握。

如果您有许多虚拟地址 space,每个都是 4 GiB;你可能会发现:

  • 大面积(例如 1 GiB)用于内核,并且需要在所有虚拟地址 space 中相同。因为这在所有的虚拟地址space中都是一样的,任何对该区域的修改都需要同时修改每一个虚拟地址space。

  • 由于其他原因,多个区域将由 2 个或更多虚拟地址 spaces 共享 - 内存映射文件、共享库、共享内存、“写入时复制”区域由“ fork()”等

  • 一些区域在相同的虚拟地址中是相同的space(例如,引用相同的“只读物理页面全为零”以实现“写时分配”策略)

  • 很多 space 将完全未使用(可能每个虚拟地址平均 2 GiB space)

对于在多个地方使用的任何东西; “指向 PTE 的指针”将为您提供一个 PTE,无论该页面使用了多少地方,都可以对其进行修改。

举个例子;假设您有一个由 40 个不同进程共享的“C 标准库”(并包含在 40 个不同的虚拟地址 spaces 中),但库的部分代码仍在磁盘上,而 PTE/s 用于那些零件说“不存在”。当任何进程需要共享库的那部分时,您会遇到页面错误(因为它还不存在)并且 OS 必须从磁盘中获取页面。在这种情况下,“指向 PTE 的指针”意味着 OS 可以更改一个 PTE(从“不存在”到“存在”)并且不需要计算需要更新多少个 PTE,然后更新 40 个不同的40 个不同虚拟地址的 PTE spaces/processes.

Isn't having an array of pointers more wasteful because it'll take double the space (4 bytes for the pointer and 4 for the PTE)?

指向 PTE 的指针数组会浪费更多 space,但很难说有多少 space(它不会是“双倍”,因为很多 PTE 会被多次使用,并且可能会增加近 50% space)。相反,PTE 数组会浪费更多 CPU 时间(在试图管理所有内容的内核代码中),并且(如果您考虑到内核使用它自己的额外 data/memory 来确定共享哪些页面其中)它实际上可能会消耗更多内存。

然而...

他们都比较糟糕;我希望讲师准备介绍 multi-level 分页(其中“每页一个指向 PTE 的指针”被“一个指向一组 PTE 的指针”取代),这是最真实的 CPU的使用。