巨页内存与Qemu/KVM虚拟化内存优化

前言

在虚拟化环境中,需要对虚拟机的优化,其中包括在某些情况下利用巨页内存进行内存的优化以提高虚拟机性能。那么什么是巨页内存?巨页内存有什么好处?Qemu/KVM虚拟化环境下如何使用巨页内存?本文将对这几个问题进行阐述。

从分页式内存管理说起

对于内存管理,大多数现代操作系统都采用分页式的内存管理方式。
巨页内存与Qemu/KVM虚拟化内存优化_第1张图片
依图,CPU进行内存访问大体流程:

  1. CPU将虚拟地址给MMU硬件
  2. 由MMU硬件将虚拟地址翻译成实际的物理地址

具体的数据流是这样的:

a. 虚拟地址中的p为页表地址的索引部分,d为页内偏移,p作为MMU里面Page Table Walk Unit的输入;
b. Page Table Walk Unit依据p从Page中进行查找;
c. 获得对应的物理frame number;
d. 依据frame number获得实际物理地址页的起始地址;
e. 依据页内偏移d读取对应的内存的数据。

由于Page walk是个比较耗时的过程:
巨页内存与Qemu/KVM虚拟化内存优化_第2张图片
MMU需要根据各级页表索引逐级查询。所以MMU内部引入TLB,将查询过的地址映射记录到TLB,这样对于已经查询过的页表,可以避免重复查询。
巨页内存与Qemu/KVM虚拟化内存优化_第3张图片当然TLB的大小也是有限制的,所以在TLB还没有热身或者TLB被填满后根据某些规则将某些TLB给清除掉,所以会产生TLB miss。产生TLB miss后就依旧需要进行一次正常的Page Walk。

基于TLB的内存访问的数据流是这样的:

a. 虚拟地址中的p为页表地址的索引部分,d为页内偏移,MMU先依据P去TLB进行查询;
b. 如果查询到,则为TLB hit,通过查询得到的‘f+d’就可以直接访问内存;
c. 如果没有查询到,则为TLB miss;
d. Page Table Walk Unit依据p从Page中进行查找
e. 获得对应的物理frame number;
f. 依据frame number获得实际物理地址页的起始地址;
g. 依据页内偏移d读取对应的内存的数据。

什么是巨页内存

普通内存页为4K大小。巨页则是远远大于4K的页面,巨页的大小取决于所使用的操作系统的内核版本以及不同的硬件平台,一般最小的巨页也有2M。
巨页内存与Qemu/KVM虚拟化内存优化_第4张图片

巨页内存的优缺点

巨页带来的优点:

  1. 降低TLB miss的概率: 拿普通的4KB页面和2MB的大页相比,都是使用一条页表项,能cover的内存大小却差了511倍,所以更多的使用大页能大大减少系统中页表项的数量,再加上TLB cache大小固定且有限,再再加上程序访问的地址的局部性原理,TLB miss的概率就下来了。
  2. 降低walk page table的长度: 由于大页的页表级数(PGD PUD PMD)比普通页面级数(PGD PUD PMD PTE)小1,所以在走表时会高效一些。(以普通页面是四级页表为例)。

巨页也有缺点:

  1. 可能需要对应用程序进行改造:对于传统巨页,必须使用特定的方式使用。详情参考下面巨页内存的类型及使用方式。
  2. 可能导致内存浪费:如果程序使用内存小,却申请了大页内存,会造成内存浪费,因为内存分配最小单位是页。

巨页内存的类型

  1. 传统巨页: 是指在系统中提前预留巨页,用户必须显式地通过hugetlbfs文件系统实现的mmap底层接口或者通过libhugetlbfs.so的库指定使用巨页。
  2. 透明巨页: 是指系统无须提前预留巨页,无须提前准备,进程分配内存在系统使能透明巨页策略的情况下,会自动默认优先使用巨页,用户无法觉察。

什么情况下使用巨页内存?

是否开启巨页内存需要根据工作负载的类型来决定:通常应用对内存需求较大时,可以考虑开启大内存分页。比如一个搜索引擎,需要大量在内存中的索引。有时候应用对内存的需求是隐性的。比如有的机器用来抗高并发访问,虽然平时对内存使用不高,但是当高并发到来时,应用对内存的需求自然就上去了。虽然每个并发请求需要的内存都不大, 但是总量上去了,需求总量也会随之提高。这种情况下,你也可以考虑开启大内存分页。

如果在虚拟机内有对于内存访问密集型的应用,在KVM客户机中使用huge page是可以较明显地提高客户机性能。

Qemu/KVM虚拟化如何使用巨页内存

  1. 如果是透明巨页,仅需要对Linux的host进行配置就行了,虚拟机部分自然会使用透明巨页。可以参考透明大页进行配置。
  2. 如果是传统巨页,分两种情况:
    a. 使用libvirt方式进行虚拟机管理的话,参考通过配置透明大页,提高kvm的性能进行配置。
    b. 使用命令行启动的话,参考KVM内存管理(五)—— hugepage进行配置。

依据KVM内存管理(七)—— 内存页/大页/透明大页 Stream 数据对比,使用传统巨页比使用透明巨页,虚拟机的性能会更好一点。

巨页引起的问题分析

如果程序内存占用大,TLB的miss又很多的情况下,可以使用perf工具进行分析,看是否申请了巨页却没有使用。比如查看TLB的miss多少:

perf record -e dTLB-loads -e faults -p pid
perf report

具体参考坑爹的大页内存。

虚拟化环境下利用巨页优化内存的例子

利用巨页内存加速虚拟机启动速度,请参考QEMU VFIO 内存优化探索与实践。

参考链接

  1. TLB原理
  2. Linux Memory Management
  3. 一文读懂 HugePages(大内存页)的原理
  4. Linux内存管理:大页内存原理
  5. 坑爹的大页内存
  6. KVM内存管理(七)—— 内存页/大页/透明大页 Stream 数据对比
  7. QEMU VFIO 内存优化探索与实践
  8. 通过配置透明大页,提高kvm的性能
  9. KVM内存管理(五)—— hugepage
  10. Linux内存管理之MMU的过程
  11. CPU通过MMU访问内存
  12. 透明大页

你可能感兴趣的:(虚拟化,linux,架构,系统架构,运维)