昇腾社区首页
中文
注册

开启大页内存池

在Linux操作系统上运行内存需求量较大的应用程序时,由于其采用的默认页面大小为4KB,因而将会产生较多TLB Miss和缺页中断,从而大大影响应用程序的性能。当操作系统使用大页内存时,将会大大减少TLB Miss和缺页中断的数量,显著提高应用程序的性能。大页内存分为两种,一种是标准大页,标准大页适合那些需要高性能和细粒度控制的应用程序,适用于对内存管理和性能有严格要求的场景。另一种是透明大页,透明大页适合那些希望简化配置并自动优化内存使用的应用程序,尤其适用于大多数通用场景,可根据需要来选择开启哪种大页。

malloc使用大页和tmpfs使用大页特性已在openEulerOS、CentOS场景下验证,由于不同OS命令使用上存在差异,无法保证在其他操作系统均能支持。glibc动态库大页特性为openEulerOS自研特性,仅支持openEulerOS,其他操作系统暂不支持。

以下为各优化手段对大页内存支持的情况,各优化手段可搭配使用:

表1 大页内存优化手段

优化手段

支持透明大页

支持标准大页

是否需要重启物理机

malloc使用大页

支持,(glibc低版本不支持,高版本支持,参考malloc使用大页

支持

tmpfs使用大页

支持

不支持

glibc动态库大页

不支持

支持

标准大页(HugePages)技术于Linux Kernel 2.6版本被引入到内核,可通过uname -r确认当前内核版本是否大于2.6。

使能OS开启透明大页内存

开启透明大页前使用“getconf PAGESIZE”检查当前Linux操作系统页大小,若显示“4096”则表明当前操作系统默认使用的4K页内存,建议开启透明大页;若显示“65536”则表明当前操作系统使用的是64K页内存,此时透明大页2MB仅能覆盖32个基础页,无法有效缩小页延迟或者减少TLB miss,建议关闭透明大页。

  1. 确认透明大页是否开启:

    执行命令cat /sys/kernel/mm/transparent_hugepage/enabled确认透明大页是否启动,若回显结果为[always]则表明已开启透明大页。一般透明大页是默认开启的。

  2. 执行以下命令,开启透明大页:
    echo always > /sys/kernel/mm/transparent_hugepage/enabled

    需要注意的是采用这种方式开启透明大页,重启服务器后会失效。

使能OS开启标准大页内存

  • 临时启用标准大页内存池
    方法一(推荐采用此方法,不需要重启机器):
    # vm.nr_hugepages的值即为2M标准大页的数量,申请标准大页会导致OS内存相应减少,建议按需设置对应大小
    sysctl -w vm.nr_hugepages=1024
    方法二:
    # 首先确认当前环境有几个node节点
    ls /sys/devices/system/node/ | grep node

    每个NUMA节点都写入对应数量的值,这个值表示各个节点待分配的2M标准大页的数量,建议每个节点分配内存为:待申请2M标准大页内存池总数量/node数量。
    echo 512 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
    echo 512 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
    • 采用方法二配置标准大页时,x86和Arm标准大页的配置方式有所不同,Arm机器需要针对NUMA各个节点都配置大页才能保证各个CPU能够访问大页内存池。
    • Arm机器若已经确定需要使用哪几个node(例如通过绑核等手段限定使用哪几个node时),可以仅设置需要使用的node节点。
    申请完成后使用如下命令确认大页已完成分配。
    cat /proc/meminfo | grep Huge 

  • 永久启用标准大页内存池

    修改启动项配置属于危险操作,请谨慎修改启动项配置,建议采用临时分配大页的方式申请大页内存池。

    • 执行以下命令,查看Linux启动项信息,确认当前系统启动项名称。(一台机器可以安装多个内核版本,请先确认当前正在运行的内核版本对应的是哪个启动项)
      grubby --info=ALL | grep `uname -r`

      kernel对应的值就是当前系统启动项内核名称,也就是我们需要设置大页内存的内核。

    • 更新系统启动项参数。
      grubby --update-kernel=/boot/vmlinuz-4.18.0-193.el8.aarch64 --args="default_hugepagesz=2M hugepagesz=2M hugepages=5000" 
      • 更新对应启动项参数,update-kernel后面的参数即上一步获取的kernel后面对应的字符串。
      • default_hugepagesz表示系统默认的大页内存大小,hugepagesz表示系统可选哪些大小的大页,hugepages表示设置每种size的大页最多可申请多少个。
      • 一般推荐选择2M大小作为大页size,可申请大页内存数量一般建议设置5000以上,内核版本越高需要的大页内存可能也会更高。
    • 重启物理机。
      reboot
      • 申请一定大小的大页内存,相应的OS可用内存大小也会等量减少,建议选取合适的大小,一般设置5000个2M大页即可(申请大页内存大小为各种size的大页内存 * 大页内存数量之和,以上述例子为例,hugepagesz=2M仅设置了一种size的大页,且hugepages=5000,因此系统会预分配5000 * 2M = 9.7G)。
      • 若大页内存数量过小,而开启相关优化手段后,程序可能引起大页内存池内存不够导致进程coredump,可以通过dmesg | tail检查系统日志是否有"PID xxx killed due to inadequate hugepage pool"。

      • 上述大页内存配置方法仅支持在物理机上,不适用于虚拟机配置标准大页。
      • 设置完启动项参数之后,必须重启系统才能生效。
    • 删除启动项参数。
      grubby --update-kernel=/boot/vmlinuz-4.18.0-193.el8.aarch64 --remove-args="hugepages hugepagesz default_hugepagesz"

      删除启动项之后同样需要重启系统才能生效。

    • 确认配置是否生效。

    重启系统之后,可以通过命令cat /proc/cmdline确认当前系统启动时是否带有大页相关参数。也可使用cat /proc/meminfo | grep Huge来查看当前系统可用的大页内存大小。其中HugePages_Total表示总共可用大页数量,HugePages_Free表示当前系统可用大页数量。若HugePages_Total为你所设置的数量,则表明大页内存启用成功;若这个数量为0,则表明未启用大页内存。