我想在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)。
答案 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 tools 和 manual of the API 获取帮助。