X86 多级分页如何节省内存?

X86 多级分页如何节省内存?,x86,operating-system,paging,virtual-address-space,X86,Operating System,Paging,Virtual Address Space,我对多级分页方案的概念感到困惑 设一个32位虚拟地址,一页为4kib,那么我将有220页/页的表项。 让一个页表条目的大小为4字节,因此页表的大小为220*4字节 如果我将虚拟地址划分为10 | 10 | 12,那么我理解的是: 我有一个页表目录,它由虚拟地址的最重要的10位索引,因此它有210个条目并指向210个不同的页表(即,在第二级)。 每一个二级表也可以由(中间)10位索引,相应的条目将保存实际的页面帧号 我的问题是: 这完全正确吗 页面目录和页面表的大小是否相同 多级分页方案如何节省

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

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

如果我将虚拟地址划分为
10 | 10 | 12
,那么我理解的是:

我有一个页表目录,它由虚拟地址的最重要的10位索引,因此它有210个条目并指向210个不同的页表(即,在第二级)。
每一个二级表也可以由(中间)10位索引,相应的条目将保存实际的页面帧号

我的问题是:

  • 这完全正确吗
  • 页面目录和页面表的大小是否相同
  • 多级分页方案如何节省内存

是的,完全正确。如果只有一级页表和每个条目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)
这节省了一些字节(4mib-8kib),但有一个缺点:将虚拟地址转换为物理地址需要一个额外的内存引用。这里,TLB(翻译查找缓冲区)开始发挥作用。它是一个(与一级缓存相比)小型缓存,在硬件中存储虚拟地址与物理地址的关联。这里使用的是特殊硬件,与Hash表(C++中的代码> STD::unOrdEdEdMult/Cuff>)相比,硬件实现的速度快,


这是x86体系结构中使用的默认32位分页方案。x86-64在某种程度上改变了这种机制,使页面表的级别更高,页面大小更大(2个MiB、4个MiB,甚至1个GiB),物理地址空间更大(PAE最多64个GiB),从而导致页面表的级别更高。x86-64的虚拟地址大小为48位,这导致每个进程(几个TiB)有一个巨大的地址空间



请注意页面和页面框架之间的区别。页面是数据,页面框架是物理内存中页面映射的区域。
页面大小=x*页面框架大小的系统,其中
x>1

感谢您的快速响应!第一级页面目录将有2^10个条目指向一个第二级页面,对吗?i、 e,2^10个第二级页数!!所以总大小应该是(2^10字节*4(页面直接大小)+2^10(可能的二级表的数量)*2^10字节*4(每个二级表的大小))?请更正。@ashish部分更正。页面表的大小由页面目录的大小+页面表的大小组成,默认x86设置产生8 kib。它不会再乘以2^10字节。我同意你的观点。但从逻辑上讲,若您认为内存中存在的第二级表的数量等于页面目录中的条目数量,那个么页面目录中就有。我想我在页面目录中有2个条目,用于2个不同的进程。每个入口指向2个大小不同的页面表。因此,大小将是页面目录的大小+每个页面表的大小(即2)。@ashish如果您有自己喜欢的答案,请接受它,以便将此问题标记为已解决。@ashish我认为您的陈述“认为我在页面目录中有2个条目用于2个不同进程”是错误的。不同的进程都有自己的页面目录,经过一些研究,我了解到多级分页可以节省内存,因为它不会为每个页面表分配内存,而是只在需要时为页面表分配内存。进程通常不使用整个地址空间,因此为映射未使用的虚拟地址分配内存(在单级分页的情况下)是一种过度消耗。多级分页通过只映射已使用的虚拟地址来节省内存。