为什么Linux内核不使用大页面?

noh*_*oha 4 c memory-management x86-64 linux-kernel huge-pages

在我浏览的过程中,我遇到了一个叫做大页面的东西,大页面机制使得使用第二级和第三级页表中的条目映射2M甚至1G页面成为可能,并且正如内核文档本身所说:

大页的使用大大减轻了TLB的压力,提高了TLB的命中率,从而提高了系统的整体性能。

我也浏览了内核源代码,但没有看到MAP_HUGETLBwhen it comes to的任何用法mmap。事实上,默认/proc/sys/vm/nr_hugepages设置为。0这是为什么?这是否意味着内核根本不需要大页面?有哪些必须使用大页面的场景示例?

举例来说:

hugepage = mmap(0, getpagesize() * 4, PROT_WRITE | PROT_READ,
                    MAP_ANON | MAP_HUGETLB | MAP_PRIVATE, 0, 0);
Run Code Online (Sandbox Code Playgroud)

Mar*_*lli 5

Linux内核对大页的处理方式主要是让系统管理员从用户空间对其进行管理。这主要是因为尽管听起来很酷,但大页面也有缺点:例如,它们无法交换到磁盘这个 LWN 系列的大页面提供了有关该主题的大量信息。

默认情况下,没有保留大页,可以通过启动参数在启动时保留它们hugepagesz=hugepages=为多个大页大小指定多次)。/proc/sys/vm/nr_hugepages大页也可以在运行时通过和保留/sys/kernel/mm/hugepages/hugepages-*/nr_hugepages.../nr_overcommit_hugepages此外,如果设置高于,它们可以由内核“动态”保留.../nr_hugepages。这些数字反映在/proc/meminfo各种HugePages_XXX统计信息下,这些统计信息针对默认的大页面大小 ( Hugepagesize)。

文件支持的映射仅在文件驻留在hugetlbfs文件系统中时支持大页,并且仅支持挂载时指定的特定大小(挂载选项pagesize=)。hugeadm除其他外,命令行工具还可以提供有关当前安装的FShugetlbfs的信息--list-all-mounts。想要在系统上安装的一个主要原因hugetlbfs是在 QEMU/libvirt 来宾中启用大页面支持。

以上所有内容都涵盖了使用MAP_HUGETLB.


Linux 还支持透明大页(THP)。当内核需要时,普通页面可以透明地变成巨大的(反之亦然,现有的透明巨大页面可以被分解为普通页面)。这不需要MAP_HUGETLB, 并且无论nr_hugepages在 sysfs 中如何。

还有一些 sysfs 旋钮可以控制 THP。最值得注意的是/sys/kernel/mm/transparent_hugepage/enabledalways意味着即使没有用户空间程序主动建议,内核也会尝试创建 THP;madvise意味着只有当用户空间程序建议它通过时它才会这样做madvise(addr, len, MADV_HUGEPAGE)never意味着他们是残疾人。always您可能会在现代 Linux 发行版(例如最新版本的 Debian 或 Ubuntu)中看到默认设置。

例如,使用mmap(0x123 << 21, 2*1024*1024, 7, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)set /sys/kernel/mm/transparent_hugepage/enabledto进行操作always应该会产生 2M 透明大页面,因为请求的映射与 2M 对齐(请注意缺少MAP_HUGETLB)。


这是否意味着内核根本不需要大页面?有哪些必须使用大页面的场景示例?

一般来说,您实际上并不需要任何类型的大页面,没有它们您也可以很好地生活。它们只是一种优化。正如 @Mgetz 在上面的评论中提到的,它们有用的场景是对非常大的文件进行大量随机内存访问的情况(对于数据库来说很常见)。在这种情况下最小化 TLB 压力可以显着提高性能。