我有一个使用mmap()
和共享内存来高效访问大型数据库文件的程序。我想尝试使用大页面来加速该程序。
我认为一个快速简便的方法是将数据库文件复制到Linux系统的hugetlbfs目录中,并在旧位置创建一个符号链接。
然而,这样做不起作用,因为cp
命令无法写入该文件。我怀疑只能通过调用ftrunc()
和mmap()
系统调用来创建文件并向其中写入。除非有现成的工具,否则我可能会尝试编写一个复制工具来实现这一点。
我正在寻找其他在Linux中使用大页面进行共享内存映射的好方法。
我有一个使用mmap()
和共享内存来高效访问大型数据库文件的程序。我想尝试使用大页面来加速该程序。
我认为一个快速简便的方法是将数据库文件复制到Linux系统的hugetlbfs目录中,并在旧位置创建一个符号链接。
然而,这样做不起作用,因为cp
命令无法写入该文件。我怀疑只能通过调用ftrunc()
和mmap()
系统调用来创建文件并向其中写入。除非有现成的工具,否则我可能会尝试编写一个复制工具来实现这一点。
我正在寻找其他在Linux中使用大页面进行共享内存映射的好方法。
这是一个老问题了。但是既然没有人回答,而我实际上也想尝试使用巨大页面支持(出于不同的原因),那么我将提供一个答案。
虽然在现代内核中巨大页面现在已经是透明的,但您仍然可以获得更多的控制。
这些函数可能是您正在寻找的。
get_huge_pages(), free_huge_pages(), get_hugepage_region(), free_hugepage_region()
您需要安装libhugetlbfs,它是hugetlbfs的包装器。
这里有一篇Linux Weekly的文章,你可能会觉得很有帮助。巨大页面-第1部分(介绍)
巨大页面是一种通过将多个连续的物理内存页面(例如4KB长)映射到单个巨大页面(例如2 MB、1 GB等)来节省TLB缺失的方法。Linux提出了两种机制:
除此之外,还提供了一个可选的用户空间库libhugetlbfs,以提供用户友好的API和工具,以便为静态链接程序的堆、代码和数据段使用巨大页面。该库隐藏了内核提供的“原始”接口。根据应用程序的不同,这可能很有用或者不够灵活。
对于问题中的数据库示例问题,想法是在 hugetlbfs 文件系统中创建文件(它实际上是一种基于大内存页面的 RAM 文件系统),将文件扩展(使用 ftrunc())到巨大页面大小的倍数,将文件映射到内存中,并使用这些内存区域作为缓冲区来读/写数据库文件。性能得到提高,因为访问内存页面所需的 TLB 条目更少。此 answer 提供了有关如何使用 Linux "raw" 接口映射大页面的详细信息。