Linux系统采用hugetlbfs的特殊文件系统来加入对2MB和1GB的大页内存的支持,为了配置,先查看cpu是否支持:
# cat /proc/cpuinfo |grep --color pse
# cat /proc/cpuinfo |grep --color pdpe1gb
查看内核是否支持:
# grep -i hugetlb /boot/config-4.18.0-193.el8.x86_64
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
CONFIG_CGROUP_HUGETLB=y
# 以下两种都为y则标识支持
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
cpu的功能列表中包含pse标识支持2MB的内存大页,包含pdpe1gb支持1GB的内存大页。
查看大页内存使用情况
# grep Huge /proc/meminfo
AnonHugePages: 4089856 kB
ShmemHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 0 kB
这里面说明:
一个页面大小为:Hugepagesize: 2048 kB
内存大页数量为:HugePages_Total: 0
NUMA架构的查看:
[root@localhost ~]# cat /sys/devices/system/node/node*/meminfo|fgrep Huge
Node 0 AnonHugePages: 153600 kB
Node 0 HugePages_Total: 0
Node 0 HugePages_Free: 0
Node 0 HugePages_Surp: 0
Node 1 AnonHugePages: 30720 kB
Node 1 HugePages_Total: 0
Node 1 HugePages_Free: 0
Node 1 HugePages_Surp: 0
可以看到这个NUMA机器上并没有分配大页内存:
HugePages_Total: 0
如果分配2MB的大页内存比较简单,可以通过命令替换:
echo 1024> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
分辨率1024个2MB的大页即复制2GB的大页内存。
如果是NUMA架构,在每个先前附上的添加:
echo 1024> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
echo 1024> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
如果要分配超过1GB的大页内存,需要在Linux的启动项中设置和挂载。
1)安装
yum install libhugetlbfs
2)分配更改启动文件,添加:
transparent_hugepage=never
default_hugepagesz=1G
hugepagesz=1G
hugepages=4
分配4个大页内存,每个为1G,在centos6中是修改
/etc/grub.conf
centos7修改英文/etc/grub2.cfg文件。3)挂载将大页内存映射到空目录:
# mkdir /mnt/myhuge
# mount -t hugetlbfs nodev /mnt/myhuge
如果要开机自动设置:
# vim /etc/fstab
nodev /mnt/myhuge hugetlbfs pagesize=1GB 0 0
像DPDK等有专门的设置工具,开机的时候立即设置防止内存不足,大页内存需要连续的空间。
程序使用
这个是看资料查的,并没有实践过
HUGETLB_MORECORE=yes
LD_PRELOAD=libhugetlbfs.so
./your_program
四大页优缺点
优点:
1)大页内存的页表小很多,可以放入到TLB中,缺页中断也很少,对于内存的访问性能更好,对于占用大量内存的程序,性能提升比较明显,有的甚至可以提升到50%左右。
2)大页内存的内存页不会交换到磁盘上。
缺点:
1)必须使用特定的方式使用,并采用mmap映射或通过上面的方式指定。
2)程序使用内存小,却申请了大页内存,会造成内存浪费,因为内存分配最小单位是页。
3) 如果使用不当,可能白白浪费内存,其他程序无法使用大页内存。
五大页面内存引起的杯具
说了半天,还没有说到到大页内存导致了什么杯具那,是这样的,在一台机器上,内存本来就很小,只有4GB内存。
用Top命令查看程序内存只有不到1G的占用,当时剩余内存只有300MB,剩余内存哪里去了?
分析下内存分配:
# cat /proc/meminfo|grep Huge
HugePages_Total: 1035
HugePages_Free: 1033
HugePages_Rsvd: 62
HugePages_Surp: 0
Hugepagesize: 2048 kB
更好的工具是用atop查看,发现大页内存占用了了高达2GB的内存,却没怎么使用。
解决办法
## 禁用大页缓存
# vi /etc/sysctl.conf
vm.nr_hugepages = 0
vm.nr_hugepages_mempolicy = 0
## 生效
sysctl -p
命令执行完毕后,起到了立竿见影的效果,一下释放了2GB的内存,这可是占系统的内存一半啊,所以大页内存是否使用,还要斟酌,不然白白浪费了内存。
如果程序内存占用大,TLB的miss却很多的情况下,可以使用,具体如何查看TLB的miss多那,可以通过性能工具来进行分析:
perf record -e dTLB-loads -e faults -p pid
perf report