日期:2014-05-16  浏览次数:20621 次

Linux下hugetlbpage使用详解

就Linux应用程序而言,使用的都是虚拟地址,当应用程序读写一个指定的虚拟地址时,内存管理单元会自动进行虚拟地址到物理地址的转换。一个虚拟 地址可以映射到多个物理地址,但当前映射到哪一个物理地址取决于当前的页表(Page Table,一个虚拟地址到物理地址的映射转换表)内容,页表存储在主存储器中,查询速度相对比较慢。为了提高地址转换性能,大多数体系架构都提供一个快 速查找缓冲TLB(Translation Lookaside Buffer),TLB读写速度非常快,比如在X86体系架构上,TLB和普通的CPU CACHE并没有本质区别,只不过TLB专职用于缓存页表数据,而普通的CPU CACHE缓存实际的代码指令或数据。TLB缓冲了最近使用过的页表项,在进行虚拟地址到物理地址的转换时先查这个TLB缓冲,只有当查找TLB缓冲失败 (TLB miss)后才再去查普通页表(好像有的架构是同时进行查找?)。当然,根据局部性原理,大多数情况下应该都是查找TLB缓冲命中(TLB hit)的,所以性能得以大大提升。这整个具体的页表查找与地址转换过程不是文本描述的重点,但我们需知道如下几点:
1,TLB缓冲能大大提升虚拟地址到物理地址的转换速度。
2,TLB缓冲大小有限,只能缓存一定量的页表项目(Entry)。
3,如果一个页越大,那么一个页表项目就能表示越多的地址空间,整个TLB缓冲命中的几率就越大。
在Linux平台上,页大小普遍为4K,但根据硬件架构的不同,Linux内核也支持更大的内存页,也就是本文要介绍的HugeTLB特性。

要使用HugeTLB特性,当然需要首先打开内核的相关编译选项:

1
2
3
4
5
6
7
8
9
10
11
[root@localhost ~]# uname -a
Linux localhost.localdomain 2.6.38.8 #4 SMP Mon Oct 31 20:49:48 CST 2011 x86_64 x86_64 x86_64 GNU/Linux
[root@localhost ~]# cat /usr/src/linux-`uname -r`/.config | grep?HUGETLB
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
[root@localhost ~]#?free?-m
?????????????total?????? used???????free?????shared??? buffers???? cached
Mem:????????? 2007?????? 1920???????? 87????????? 0????????? 1???????? 10
-/+ buffers/cache:?????? 1908???????? 99
Swap:???????? 2015???????? 33?????? 1982
[root@localhost ~]#

查看HugePages信息:

1
2
3
4
5
6
7
[root@localhost ~]# cat /proc/meminfo | grep Huge
HugePages_Total:?????? 0
HugePages_Free:??????? 0
HugePages_Rsvd:??????? 0
HugePages_Surp:??????? 0
Hugepagesize:?????? 2048 kB
[root@localhost ~]#

其中:
HugePages_Total:系统当前总共拥有的HugePages数目。
HugePages_Free:系统当前总共拥有的空闲HugePages数目。
HugePages_Rsvd:系统当前总共保留的HugePages数目,更具体点就是指程序已经向系统申请,但是由于程序还没有实质的HugePages读写操作,因此系统尚未实际分配给程序的HugePages数目。
HugePages_Surp:指超过系统设定的常驻HugePages数目的数目。
Hugepagesize:每一页HugePages的大小。
虽然尝试对上面这几个字段解释了一通,但HugePages_Rsvd和HugePages_Surp貌似仍然不够清楚,下面我们以实例数据来看,不过在此之前需要讲解另外几个内核参数:

1