Hugepage 大页内存 的使用
系统启用大页内存
下述操作,需要重启机器。
不建议 通过 设置 echo 1G > /proc/sys/vm/nr_hugepages
的方式设置,因为系统不一定成功。
设置大页内存的PAGESIZE
1、grubby --update-kernel=ALL --args="hugepagesz=1G”
Centos 下(其他发行版本自行Google)
设置大页内存的PAGE个数
2、grubby --update-kernel=ALL --args="hugepages=10”
上述1、2的顺序不能乱,乱了系统就没办法在启动阶段申请PAGE了。
或者直接在一个命令中完成:
grubby --update-kernel=ALL --args="hugepagesz=1G hugepages=10”
上面的目的都是在系统启动阶段划出大页供应用进程使用。
重置参数
sudo grubby --update-kernel=ALL --remove-args="hugepages hugepagesz default_hugepagesz"
使用大页内存
使用hugetlbfs
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
void access_mem(char *ptr, unsigned long memsize)
{
unsigned long i;
for (i = 0; i < memsize; i+=4096) {
ptr[i] = 1;
}
}
int main() {
unsigned long memsize = 1000000000;
unsigned long i;
int fd = open("/dev/hugepages/fileA", O_CREAT|O_RDWR, 0600);
char *my_string = mmap(0, memsize, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
access_mem(ptr, memsize);
}
使用 perf 探测 缺页中断数,和TLB miss数,发现非常少。
sudo perf record -e dTLB-loads -e faults ./a.out
sudo perf report
得到的结果如下:
Available samples
1k dTLB-loads
7 faults
不使用hugepage的程序
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <malloc.h>
void access_mem(char *ptr, unsigned long memsize)
{
unsigned long i;
for (i = 0; i < memsize; i+=4096) {
ptr[i] = 1;
}
}
int main() {
unsigned long memsize = 1000000000;
char *my_string = malloc(memsize);
access_mem(my_string, memsize);
}
使用 perf 探测 缺页中断数,和TLB miss数,发现相对使用大页的程序而言,就多多了。
sudo perf record -e dTLB-loads -e faults ./a.out
sudo perf report
得到的结果如下:
Available samples
2K dTLB-loads
1K faults
直接使用mmap
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
void access_mem(char *ptr, unsigned long memsize)
{
unsigned long i;
for (i = 0; i < memsize; i+=4096) {
ptr[i] = 1;
}
}
int main() {
unsigned long memsize = 1000000000;
unsigned long i;
char *my_string = mmap(0, memsize, PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB/**/, -1, 0);
access_mem(my_string, memsize);
sleep(20);
munmap(my_string, memsize);
}
使用 perf 探测 缺页中断数,和TLB miss数,发现非常少。
sudo perf record -e dTLB-loads -e faults ./a.out
sudo perf report
得到的结果如下:
Available samples
970 dTLB-loads
7 faults
大页内存的优缺点
优点很明显,大页内存TLB miss 很少,缺页中断也很少,极高的提高了性能,对于那些内存操作非常频繁的业务来说,可以有效的提高性能。
缺点就是,大页内存类似专用内存,会从系统中抠出一块大内存(pagesize*nr_pages),而想要使用这块内存,应用程序必须修改程序,使用上述几种方式来使用大页。 其次,如果程序内存使用较少,却申请了大页,就造成了内存浪费的。
Redhat有另一种便捷的方式,就是 透明大页,就是开启后,任何程序都默认使用2MB的大页,不需要修改程序源码,但是也带来了内存浪费。