代码大页(Huge Pages)是基于透明大页THP(Transparent Huge Pages)进行的优化扩展,支持将应用程序和动态链接库的可执行部分放入到大页(通常是2 MB或更大)中,有助于降低程序的iTLB miss,并提升CPU的2 MB iTLB利用率,避免内存碎片化或内存膨胀问题,提高内存利用效率,适用于数据库、大型应用程序等大代码段业务场景。本文主要介绍代码大页的使用方法以及性能收益等。
根据实际的使用经验,代码大页在不同平台性能提升不同,具体与应用本身的执行方式有关。
有关代码大页中一些常用名词解释,请参见附录:名词解释。
使用限制
仅以下内核版本的Alibaba Cloud Linux镜像支持使用代码大页功能:
Alibaba Cloud Linux 2:
4.19.91-25
及以上内核版本。Alibaba Cloud Linux 3:
5.10.112-11
及以上内核版本。
您可以通过uname -r
命令查询镜像的内核版本。
使用代码大页
启用代码大页
该功能默认是关闭的,可以使用sysfs
接口进行启用。支持如下三种启用方式。
方式一:仅打开二进制和动态库大页
sudo sh -c 'echo 1 > /sys/kernel/mm/transparent_hugepage/hugetext_enabled'
方式二:仅打开可执行匿名大页
sudo sh -c 'echo 2 > /sys/kernel/mm/transparent_hugepage/hugetext_enabled'
方式三:同时打开以上两类大页
sudo sh -c 'echo 3 > /sys/kernel/mm/transparent_hugepage/hugetext_enabled'
打开代码大页功能并不意味着立即合并大页,代码大页功能是异步的。
检查是否启用代码大页
运行以下命令,查看/proc/<pid>/smaps中的FilePmdMapped
字段可确定是否使用了代码大页,FilePmdMapped
字段表示进程代码大页的使用数量(单位kB)。
sudo cat /proc/<pid>/smaps | grep FilePmdMapped | awk '{sum+=$2}END{print"Sum= ",sum}'
<pid>
需替换为您实际应用程序进程ID,可通过pidof sshd
查看进程ID。
关闭代码大页
运行以下命令,使用sysfs
接口关闭代码大页。
sudo sh -c 'echo 0 > /sys/kernel/mm/transparent_hugepage/hugetext_enabled'
关闭代码大页功能并不意味着立即拆散大页,代码大页功能是异步的。
如果一段代码曾经被合并为大页,即使关闭代码大页功能,大页缓存还是存在。
另外,支持在系统启动项中设置代码大页的状态:设置hugetext=0/1/2/3。系统启动项与您系统的GRUB版本以及系统镜像有关,请您根据实际情况进行配置。
关闭代码大页后,同时支持以下几种方式清理已使用的大页。
方式一:清理整个系统的page cache(文件缓存)
sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'
方式二:清理单个文件的page cache(文件缓存)
sudo vmtouch -e /<path>/target
说明vmtouch是一个用于检查文件是否已经加载到内存中,并且可以将文件锁定到内存或者从内存中卸载的工具。如果您没有安装vmtouch,需先执行
sudo yum install vmtouch
命令安装。<path>
需替换为您实际应用程序的文件路径。
方式三:清理遗留大页
sudo sh -c 'echo 1 > /sys/kernel/debug/split_huge_pages'
性能收益
该功能在不同平台优化效果不同,主要原因在于平台转译后备缓冲器TLB(Translation Lookaside Buffer)模块的设计。当前已知较适用场景包括数据库类业务(例如MySQL、PostgreSQL等)和Java类业务,物理机上优化效果约为5%~8%,虚拟机环境收益更佳。下面以MySQL为例,验证Arm平台上代码大页的性能收益。
如果一段代码曾经被合并为大页,即使关闭代码大页功能,大页缓存还是存在。所以在测试性能时建议通过echo 3 > /proc/sys/vm/drop_caches
清理系统的大页缓存,以确保性能测试的准确性。
假设vCPU总核数为32,测试过程中MySQL并发数分别是1、8(25%)、16(50%)、32(100%)。2 MB代码大页与普通4 KB代码页性能指标TPS(Transaction Per Second)数据对比如下:
通过上图TPS数据对比可以看出,代码大页的性能始终高于普通代码页。详细说明如下:
并发数为1时,外在的影响因素较小。此时代码大页相比普通代码页,性能提升大约6.9%。
并发数为8、16时,基本可以保证没有CPU的竞争,代码大页的性能提升大约也在6.5%以上。
并发数为32时,可能存在其他应用竞争CPU,所以TPS较低于前面的测试结果。在系统受到不确定因素扰动时,代码大页的稳定性更好,此时相比普通代码页,性能提升大约11%左右。
上图展示的是代码大页与普通4 KB代码页的iTLB数据,左图是iTLB miss数据,右图是iTLB MPKI数据。MySQL使用代码大页后:
iTLB miss大约下降了10倍左右,数值大小从原来的0.09%左右下降到0.08%左右。
iTLB MPKI大约下降了6倍左右。
除MySQL外,代码大页在PostgreSQL上也存在7%左右的性能提升。
Padding功能
Padding功能是对代码大页特性的优化,主要解决应用加载后的代码段未完全使用代码大页导致的不是最佳性能效果(未使用代码大页部分属于热点)的问题。该特性需要在启用代码大页的基础上使用,不可独立使用。例如,当二进制文件末尾剩余text段由于不足2 MB而无法使用大页时,当剩余text大小超过hugetext_pad_threshold
值,可将其填充为2MB text,保证可使用上大页。
启用Padding
运行以下命令,使用
sysfs
接口启用Padding功能。sudo sh -c 'echo [0~2097151] > /sys/kernel/mm/transparent_hugepage/hugetext_pad_threshold'
说明建议一般情况写4096即可,即
sudo sh -c 'echo 4096 > /sys/kernel/mm/transparent_hugepage/hugetext_pad_threshold'
。一般情况下,应用的代码段映射地址一般是2MB对齐(代码大页同时也做了地址对齐的优化),但紧跟的rw-p或r--p部分不一定为2 MB对齐,这种情况可能会导致
hugetext_pad_threshold
不能理想填充,存在部分代码段使用4 KB页。建议您在使用Padding功能时,将代码段和数据段2 MB对齐。对齐方法:修改默认的lds文件,在代码和数据段前加上. = ALIGN(0x200000);
即可。关闭Padding
运行以下命令,使用
sysfs
接口关闭Padding功能。sudo sh -c 'echo 0 > /sys/kernel/mm/transparent_hugepage/hugetext_pad_threshold'
附录:名词解释
代码大页功能中一些常用名词解释如下所示。
名词 | 说明 |
大页 | 大页(HugePages),也称为大内存页。是指操作系统以大于4 KB的页大小为管理单元的一种内存分配和管理方式,大页可以提高硬件TLB利用率进而提升性能。 |
透明大页 | 透明大页(Transparent Huge Pages)是一种隐式使用大页的方式,在用户进程无感知的情况下,系统后台通过启动内核线程异步扫描每一个进程的虚拟地址空间,整合合适的虚拟地址空间VMA(Virtual Memory Area)为2 MB大页。 |
代码大页 | 代码大页(Hugetext)利用透明大页相同的整合机制,仅将代码部分整合为大页,性能提升效果明显。 |
iTLB miss | 指令转换后备缓冲区iTLB(Instruction Translation Lookaside Buffer)的不命中率,iTLB命中率低,会导致CPU无法高效运行。 |
iTLB利用率 | 指令转换后备缓冲区iTLB的利用率,利用率越高,系统的性能越高。 |
iTLB MPKI | 指令转换后备缓冲区iTLB中每千条指令的未命中数据,未命中数据越小,系统的性能越高。 |
相关文档
Alibaba Cloud Linux系统也可以通过透明大页提高内存访问的效率。透明大页可以自动将小页面(通常为4 KB)合并成大页面(通常为2 MB或更大),可以减少内存访问页表项PTE(Page Table Entries)大小和访问次数,从而减轻TLB缓存的压力提升程序性能。更多信息,请参见Alibaba Cloud Linux系统中与透明大页THP相关的性能调优方法。