【问题标题】:How does multilevel paging save memory?多级分页如何节省内存?
【发布时间】:2016-01-20 10:31:55
【问题描述】:

我对多级分页方案的概念感到困惑。

假设一个 32 位虚拟地址和一页是 4 KiB,那么我将有 220 个页面/页表条目。
假设一个页表条目的大小为 4 字节,因此页表的大小为 220 * 4 字节。

如果我把虚拟地址分成10 | 10 | 12,那么我的理解是:

我有一个页表目录,它以虚拟地址的最高10位为索引,所以它有210个条目,指向210个不同页表(即第 2nd 级)。
每个第 2nd 级表又可以按(中间)10 位索引,相应的条目将保存实际的页框号。

我的问题是:

  • 这完全正确吗?
  • 页目录大小和页表大小一样吗?
  • 多级分页方案如何节省内存?

【问题讨论】:

标签: x86 operating-system paging virtual-address-space


【解决方案1】:

是的,这一切都正确。如果只有一级页表和每个条目 4 个字节,页表将有

4 GiB (maximal physical address space) / 4 KiB (size of one page frame) * 4 Bytes = 4 MiB

访问物理地址就像

(page table entry)->(offset)


为了减小这个大页表的大小,采用了多级分页方案,将大小减小到

2^10 Bytes * 4 + 2^10 Bytes * 4 = 8 KiB

并将虚拟地址的解析更改为物理地址

(page directory entry)->(page table entry)->(offset)

这节省了一些字节(4 MiB - 8 KiB),但有一个缺点:需要一个额外的内存引用才能将虚拟地址转换为物理地址。在这里,TLB(翻译后备缓冲区)开始发挥作用。它是一个(与 L1 缓存相比)小型缓存,用于存储虚拟地址与硬件中物理地址的关联。这里使用了特殊的硬件,类似于哈希表(C++ 标准库中的std::unordered_map),不同之处在于它是在硬件中实现的,因此速度更快。


这是 x86 架构中采用的默认 32 位分页方案。 x86-64、PSEPAE,通过更多级别的页表、更大的页面大小(2 MiB、4 MiB 甚至 1 GiB)和更大的物理地址空间(最多 64 GiB)稍微改变了机制与PAE),导致更多级别的页表。 x86-64 的虚拟地址大小为 48 位,导致每个进程有一个巨大的地址空间(几个 TiB)。


请注意页面和页框之间的区别。页面是数据,页框是物理内存中页面映射的区域。 系统,page's size = x * page frame's sizex > 1

【讨论】:

  • 感谢您的快速响应!第一级页面目录将有 2^10 个条目指向一对一的第二级页面,对吗?即 2^10 个二级页面!所以总大小应该是 (2^10 bytes * 4(page directory size) + 2^10(number of possible 2nd level tables) * 2^10 Bytes * 4(size of each 2nd level table)) ?请更正。
  • @ashish 部分正确。页表的大小由页目录的大小 + 页表的大小组成,在默认的 x86 设置上产生 8 KiB。 不是再次乘以 2^10 字节。
  • 我同意你的观点。但从逻辑上讲,如果您认为内存中存在的二级表的数量等于页面目录中的条目数。认为我在页面目录中有 2 个条目用于 2 个差异进程。每个条目指向 2 个不同大小的页表。所以大小将是页面目录的大小 + 每个页表的大小(即 2)。
  • @ashish 如果您有最喜欢的答案,请接受它,以便将此问题标记为已解决。
  • @ashish 我认为您的陈述“认为我在页面目录中有 2 个条目用于 2 个差异进程”是错误的。不同的进程都有自己的页目录,经过一番研究,我了解到多级分页可以节省内存,因为它不会为每个页表分配内存,它仅在需要时为页表分配内存。进程通常不使用整个地址空间,因此分配内存来映射未使用的虚拟地址(单级分页的情况)是一种过度杀伤力。多级分页通过仅映射使用的虚拟地址来节省内存。
猜你喜欢
  • 2015-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 2011-10-07
  • 2021-12-04
  • 2011-12-26
  • 1970-01-01
相关资源
最近更新 更多