Hugepage内存管理机制,故名就是大页内存管理,对应就是页管理,之所以有Hugepage机制诞生,正是因为之前的页管理有了很大问题。

Linux在内存管理中采用受保护的虚拟地址模式,在代码中地址分为3类:逻辑地址、线性地址、物理地址。程序使用具体内存简单说就是逻辑地址通过分段机制映射转化为线性地址,然后线性地址通过分页机制映射转化为物理地址的过程,而在实际使用中,仅将线性地址映射为物理地址的过程中,需要从内存中读取至少四次页目录表(Page Directory)和页表 (Page Table),为了加快内核读取速度,CPU在硬件上对页表做了缓存,就是TLB。

线性地址先从TLB获取高速缓存内存,如果不存在就从内存表获取,如果有直接的映射,直接从内存读取,没有则产生缺页中断,从新分配物理内存,或者从硬盘上将swap读取。具体图示如下:

普通页管理就不在此赘述,建议有个基本了解之后再看Hugepage的管理方式。

普通页大小是每个4K,而Hugepage在X86_64下是2M大小。

如果是4K页的寻址如下:

其中offset只能需找12位的地址。

Hugepage的offset则可以寻找20位的地址,如此,同样48位地址寻址,就少读取一次内存。如果使用小页的话,若访问一个 2M 的内存,那么至少需要放问 512 × 4 次。而如果使用大页的话,如果访问 2M 页表,需要访问内存次数为 3 次,效率相差还是比较大的。

其中dbaleet中提到了一种解释可以节约内存,这种解释是有问题的,每个进程不会占用全部内存,它的线性区只会映射到使用的页,每个page table也只初始化这部分,整体上看,所有页表初始化的个数和页数是一致的,节约内存不是Hugepage的出发点。

由于页扩大了,那边页的个数就减少了,此时整个页表项体积页相对减少,方便内存管理,更重要的是,寻址的效率提升更多,这才是Hugepage的目的。

除了提高页表的查询效率和较小的节省了页表项开销,它还有一个功能:Not swappable ,不可交换,内存数据始终在物理内存中,不会交换到磁盘上的,如此可以让高性能程序保持稳定,(PS:我以为这应该是一个所有程序共用一个页表导致的缺陷,而非特意设计的功能,类似的功能mlock函数可以轻松实现)。


hugepage内存管理机制来自于OenHan

链接为:http://oenhan.com/linux-kernel-khugepaged

发表回复