从Alibaba Cloud Linux 2(内核版本4.19.91-25)和Alibaba Cloud Linux 3(内核版本5.10.112-11)开始支持代码大页功能。本文为您介绍代码大页的功能、使用方法以及性能收益等。

功能介绍

代码大页基于透明大页THP(Transparent Huge Pages)相同的整合机制,稳定性和安全性皆可保证,同时由于应用的代码部分本身有限,可以确保代码大页使用过程中不会出现内存碎片化或内存膨胀等问题。代码大页主要为大代码段业务服务,您可以通过该功能将应用程序和动态链接库的可执行部分放入到大页(Huge Pages)中,降低程序的iTLB miss,提升CPU的2 MB iTLB利用率,从而提升程序性能。
说明 根据实际的使用经验,代码大页在不同平台性能提升不同,具体与应用本身的执行方式有关。

有关代码大页中一些常用名词解释,请参见附录:名词解释

使用代码大页

启用代码大页

该功能默认是关闭的,可以使用sysfs接口进行启用。支持如下三种启用方式。
  • 方式一:仅打开二进制和动态库大页
    echo 1 > /sys/kernel/mm/transparent_hugepage/hugetext_enabled
  • 方式二:仅打开可执行匿名大页
    echo 2 > /sys/kernel/mm/transparent_hugepage/hugetext_enabled
  • 方式三:同时打开以上两类大页
    echo 3 > /sys/kernel/mm/transparent_hugepage/hugetext_enabled
说明 打开代码大页功能并不意味着立即合并大页,代码大页功能是异步的。

关闭代码大页

运行以下命令,使用sysfs接口关闭代码大页。
echo 0 > /sys/kernel/mm/transparent_hugepage/hugetext_enabled
说明
  • 关闭代码大页功能并不意味着立即拆散大页,代码大页功能是异步的。
  • 如果一段代码曾经被合并为大页,即使关闭代码大页功能,大页缓存还是存在。

另外,支持在系统启动项中设置代码大页的状态:设置hugetext=0/1/2/3。系统启动项与您系统的GRUB版本以及系统镜像有关,请您根据实际情况进行配置。

关闭代码大页后,同时支持以下几种方式清理已使用的大页。
  • 方式一:清理整个系统的page cache(文件缓存)
    echo 3 > /proc/sys/vm/drop_caches
  • 方式二:清理单个文件的page cache(文件缓存)
    vmtouch -e /<path>/target
    说明 <path>需替换为您实际应用程序的文件路径。
  • 方式三:清理遗留大页
    echo 1 > /sys/kernel/debug/split_huge_pages

检查是否启用代码大页

运行以下命令,查看/proc/<pid>/smaps中的FilePmdMapped字段可确定是否使用了代码大页,FilePmdMapped字段表示进程代码大页的使用数量(单位kB)。
cat /proc/<pid>/smaps | grep FilePmdMapped | awk '{sum+=$2}END{print"Sum= ",sum}'
说明 <pid>需替换为您实际应用程序进程ID,可通过pidof sshd查看进程ID。

性能收益

该功能在不同平台优化效果不同,主要原因在于平台转译后备缓冲器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数据
通过上图TPS数据对比可以看出,代码大页的性能始终高于普通代码页。详细说明如下:
  • 并发数为1时,外在的影响因素较小。此时代码大页相比普通代码页,性能提升大约6.9%。
  • 并发数为8、16时,基本可以保证没有CPU的竞争,代码大页的性能提升大约也在6.5%以上。
  • 并发数为32时,可能存在其他应用竞争CPU,所以TPS较低于前面的测试结果。在系统受到不确定因素扰动时,代码大页的稳定性更好,此时相比普通代码页,性能提升大约11%左右。
iTLB数据上图展示的是代码大页与普通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功能。
    echo [0~2097151] >  /sys/kernel/mm/transparent_hugepage/hugetext_pad_threshold
    说明 建议一般情况写4096即可,即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功能。
    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中每千条指令的未命中数据,未命中数据越小,系统的性能越高。