如何使用Linux hugetlbfs实现文件的共享内存映射?

6

我有一个使用mmap()和共享内存来高效访问大型数据库文件的程序。我想尝试使用大页面来加速该程序。

我认为一个快速简便的方法是将数据库文件复制到Linux系统的hugetlbfs目录中,并在旧位置创建一个符号链接

然而,这样做不起作用,因为cp命令无法写入该文件。我怀疑只能通过调用ftrunc()mmap()系统调用来创建文件并向其中写入。除非有现成的工具,否则我可能会尝试编写一个复制工具来实现这一点。

我正在寻找其他在Linux中使用大页面进行共享内存映射的好方法。


“透明巨页面”可能为您提供所有好处,而无需进行特殊编码或将所有数据复制到hugetlb ramdisk中。此功能在最新内核中是标准的,Red Hat和Suse都已将其移植到其最新企业版本中(分别为RHEL 6更新2和SLES 11 SP2)。 - Nemo
1
@Nemo:根据文档,透明大页目前只适用于私有匿名内存。我希望能够使用共享文件映射的某些东西来解决这个问题。 - Zan Lynx
嗯,听起来这是“未来工作”的一部分。好吧,传统的hugetlbfs也只是匿名页面(一个ramdisk,基本上是相同的东西)。所以看起来Linux目前不支持你正在尝试做的事情。 - Nemo
2
@Nemo:是的,但在RAM磁盘中它们被命名为匿名页面,应该能够以共享访问的方式打开。 - Zan Lynx
Oracle建议不要使用透明大页。他们的建议可能值得一读,特别是如果您担心动态内存分配可能超出您的控制。这样的建议很容易被认为是普遍的。 - Jeff Holt
因此,Oracle建议在其数据库产品中禁用它们。所给出的解释非常简洁。只要我不需要运行Oracle数据库服务器,我宁愿保持默认设置,从内核开发人员和所有主要分销商(包括您提供链接的Oracle)的角度来看,这似乎是可以接受的。 - ypnos
2个回答

0

这是一个老问题了。但是既然没有人回答,而我实际上也想尝试使用巨大页面支持(出于不同的原因),那么我将提供一个答案。

虽然在现代内核中巨大页面现在已经是透明的,但您仍然可以获得更多的控制。

这些函数可能是您正在寻找的。

get_huge_pages(), free_huge_pages(), get_hugepage_region(), free_hugepage_region()

您需要安装libhugetlbfs,它是hugetlbfs的包装器。

这里有一篇Linux Weekly的文章,你可能会觉得很有帮助。巨大页面-第1部分(介绍)


0

巨大页面是一种通过将多个连续的物理内存页面(例如4KB长)映射到单个巨大页面(例如2 MB、1 GB等)来节省TLB缺失的方法。Linux提出了两种机制:

  • 透明巨大页面(THP)在内核中透明地管理;
  • 用户控制的巨大页面由用户空间应用程序管理。

除此之外,还提供了一个可选的用户空间库libhugetlbfs,以提供用户友好的API和工具,以便为静态链接程序的堆、代码和数据段使用巨大页面。该库隐藏了内核提供的“原始”接口。根据应用程序的不同,这可能很有用或者不够灵活。

对于问题中的数据库示例问题,想法是在 hugetlbfs 文件系统中创建文件(它实际上是一种基于大内存页面的 RAM 文件系统),将文件扩展(使用 ftrunc())到巨大页面大小的倍数,将文件映射到内存中,并使用这些内存区域作为缓冲区来读/写数据库文件。性能得到提高,因为访问内存页面所需的 TLB 条目更少。

answer 提供了有关如何使用 Linux "raw" 接口映射大页面的详细信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接