我做了什么:1。用root启用大页面(我的系统支持1MB大页面)
$echo 20 > /proc/sys/vm/nr_hugepages
2.将庞大的页面文件系统安装到/ mnt / hugepages
$mount -t hugetlbfs nodev /mnt/hugepages
3.在巨大的页面文件系统中创建文件
$touch /mnt/hugepages/hello
4.然后使用mmap将大页面映射到地址0,如下面的代码所示
#define FILE_NAME "/mnt/hugepages/hello"
#define PROTECTION (PROT_READ | PROT_WRITE) // page flag
#define LENGTH (1024*1024*1024) // huge page size
#define FLAGS (MAP_SHARED) //page flag
#define ADDR (void *) (0x0UL) //starting address of the page
fd = open(FILE_NAME, O_CREAT | O_RDWR, 0755);
if (fd < 0) { //
perror("Open failed");
exit(1);
}
// allocate a buffer using huge pages
buf = mmap(ADDR, LENGTH, PROTECTION, FLAGS, fd, 0);
if (buf == MAP_FAILED) {
perror("mmap");
unlink(FILE_NAME);
exit(1);
}
该计划输出: mmap:无法分配内存
答案 0 :(得分:2)
Linux仅支持私有匿名映射的大页面(不受文件支持)。即你只能为堆栈,数据和堆启用大表。
答案 1 :(得分:1)
目前尚不清楚OP是在谈论1GB页面大小还是在ARMv7上,并且确实有1MB的页面大小(主题与描述不符)。这个答案是指使用1GB页面大小。
无论如何,如果你想要1GB的页面大小,你必须在启动时启用它(除非你的内存非常干净,因为只有你拥有hugepagesz连续的可用内存才能分配大页面)。要启用gigabyte hugepages,请将 hugepagesz = 1GB hugepages = n 添加到GRUB_CMDLINE_LINUX,其中n是要添加的1GB页面的数量。
您现在可以使用get_huge_pages()( yah!)等接口使用1GB大页面,但仍然无法使用shm_get / mmap( boo!)进行分配。这两个都没有指定hugepagesz的机制,需要一个解决方法,将 default_hugepagesz = 1GB 设置为内核启动命令行的附加参数。
一旦你设置了所有三个参数告别TLB故障并沉浸在1GB页面大小的荣耀中!...除非你掌权,然后你应该沉浸在16GB页面大小的荣耀中;) 。
# Script to create /hugepages mount point and enable 1GB hugepages
# For RHEL (6) Systems!
#
# MAKE SURE YOU KNOW WHAT THIS SCRIPT DOES BEFORE RUNNING!
echo "hugetlbfs /hugepages hugetlbfs rw,mode=0777,pagesize=1G 0 0" \
>> /etc/fstab
mkdir /hugepages
sed 's/rhgb quiet/hugepagesz=1GB default_hugepagesz=1GB hugepages=16 selinux=0/' /etc/default/grub > grub
cp /etc/default/grub grub.old
mv -f grub /etc/default/grub
grub2-mkconfig > /etc/grub2-efi.cfg
# Now reboot
答案 2 :(得分:0)
请注意,您还需要使用ftruncate(2)
来调整文件的大小,以便它实际保存您使用的内存量。 mmap(2)
仍可用于零大小的文件,但在尝试访问内存时,您将获得SIGBUS
:
使用映射区域可能会产生以下信号:
...
SIGBUS尝试访问与文件不对应的缓冲区的一部分(例如,超出文件末尾,包括另一个进程截断文件的情况)。
(来自mmap(2)
。)
要检查该区域是否真的使用了大页面,您可以检查/proc/[pid]/smaps
(在Linux上的proc(5)
中有记录)。检查内存区域VmFlags
是否包含ht
。
修改强>
顺便看看libhugetlbfs了吗?