Linux上内存映射文件的大页面

时间:2017-05-19 02:56:36

标签: c linux mmap tlb huge-pages

我想在Linux 3.13上使用包含内存映射文件的Huge Pages。

首先,在Ubuntu上我这样做是为了分配10个大页面:

sudo apt-get install hugepages
sudo hugeadm --pool-pages-min=2048K:10

然后我运行了这个测试程序:

#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>

int main(void)
{
    size_t size = 2 * 1024 * 1024; /* 1 huge page */

    int fd = open("foo.bar", O_RDWR|O_CREAT, 0666);
    assert(fd >= 0);
    int rc = ftruncate(fd, size);
    assert(rc == 0);

    void* hint = 0;
    int flags = MAP_SHARED | MAP_HUGETLB;
    void* data = mmap(hint, size, PROT_READ|PROT_WRITE, flags, fd, 0);
    if (data == MAP_FAILED)
        perror("mmap");
    assert(data != MAP_FAILED);
}

EINVAL总是失败。如果您将flags更改为MAP_PRIVATE|MAP_ANONYMOUS,那么它可以正常工作,但当然它不会向文件写入任何内容。

我还尝试在madvise()之后使用mmap()而不使用MAP_HUGETLB

    rc = madvise(data, size, MADV_HUGEPAGE);
    if (rc != 0)
        perror("madvise");
    assert(rc == 0);

如果未使用EINVAL,这也会失败(MAP_ANONYMOUS)。

有没有办法在磁盘上启用内存映射文件的大页面?

要清楚,我正在寻找一种方法在C中执行此操作 - 我不是要求应用于现有可执行文件的解决方案(那么问题将属于SuperUser)。

2 个答案:

答案 0 :(得分:4)

您使用的基础文件系统看起来不支持使用大页面的内存映射文件。

例如,对于ext4,此支持仍在开发中as of January 2017,尚未包含在内核中(截至2017年5月19日)。

如果运行应用了该补丁集的内核,请注意您需要在文件系统挂载选项中启用大页面支持,例如将huge=always添加到/etc/fstab中的第四列,以用于文件系统期望,或使用sudo mount -o remount,huge=always /mountpoint

答案 1 :(得分:0)

这里有一个混淆:可以通过原始内核接口或/和用户空间库 (libhugetlbfs) 和附带工具(例如 hugeadm)使用大页面。< /p>

如果您想将内存区域mmap() 转换为大页面。您正在使用“原始内核接口”。为此,answer 中有一个食谱。

如果您想使用用户空间库 (libhugetlbfs),请从 manuals of the toolsmanual of the API 获取帮助。