Arm64架构内存页大小配置指南:提升性能的关键技巧

本文深入探讨Arm64架构中内存页大小的配置方法,分析4K/16K/64K页面对系统性能的影响,并提供在Ampere CPU上配置大内存页的详细操作指南,适用于数据库、虚拟化等内存密集型应用场景。

理解Arm64架构的内存页大小

Arm64架构与x86的主要区别之一,是可以在CPU的内存管理单元(MMU)中配置4K、16K或64K的内存页大小。本文总结了内存页大小的概念、在Linux系统上的配置方法,以及何时应该为应用程序使用不同的页大小。

内存页大小介绍

正如我们在诊断和修复Arm64原子操作的页错误性能问题中讨论过的,操作系统为应用程序提供虚拟内存地址空间,并通过页表将物理内存页映射到虚拟内存地址。CPU随后提供名为转译后备缓冲器(TLB)的机制,确保最近访问的内存页可以通过L1或L2 CPU缓存更快地被识别和读取。

x86架构的物理内存页(称为granules)大小固定为4KB。而在Ampere Altra®或AmpereOne®等ARM64系统上,开发者可以配置物理内存页大小为4KB、16KB或64KB。

何时使用更大的页大小?

由于改变页大小会影响系统的内存效率和性能,理解何时使用更大的页大小以及涉及的权衡非常重要。更大的页大小可能导致内存使用效率降低,因为页面可能未被完全利用。

例如,如果我们在内存中存储7KB数据:

  • 在4KB页系统中会使用两个4KB页面(共8KB),效率为87.5%
  • 在64KB页系统中会使用一个64KB页面,效率仅为11%

但MMU和操作系统内核足够智能,会利用之前分配但未满的连续内存块进行后续分配。如果同一进程后续分配32KB内存:

  • 64KB页系统仍只使用一个页面(共39KB占用)
  • 4KB页系统则需要管理10个4KB页面

第二个权衡是页表查找缓存未命中导致的性能问题。每级缓存(L1、L2、系统级缓存)的TLB中只存储相对少量的页表项。更大的页大小意味着这些TLB项能覆盖更大的物理内存范围。

以Ampere Altra和Altra Max处理器为例:

  • L1数据TLB有48个条目
  • L2 TLB有1280个条目

这意味着:

  • 4KB粒度时:L1 TLB可缓存192KB物理内存地址,L2 TLB可覆盖5MB
  • 64KB页大小时:L1数据TLB增至3MB,L2 TLB增至80MB

每次TLB缓存未命中都会增加页遍历时间,导致CPU流水线停顿。更大的页大小意味着更少的缓存未命中,从而提升内存密集型工作负载的性能。同时,更大的连续内存区域也能改善I/O性能。

适合使用大内存页的应用包括:

  1. 数据库系统:大量内存缓存和磁盘I/O
  2. 虚拟化基础设施:虚拟机镜像通常占用数百MB到数百GB内存
  3. 持续集成构建服务器:如Linux内核编译等高吞吐量工作负载
  4. 网络/I/O密集型应用:对象缓存、负载均衡器、防火墙等
  5. AI推理:执行训练模型时的内存和CPU密集型工作负载

建议通过"perf"工具测量TLB停顿(stall_backend_tlb和stall_frontend_tlb)来评估大页面的潜在收益。计算公式:(stall_frontend_tlb + stall_backend_tlb)/cycles可作为可能节省时间的上限估计。

在Ampere CPU上配置大页大小

更改内存页大小需要运行支持所需大小的内核。主流云操作系统(如RHEL、Oracle Linux、SUSE、Ubuntu)都提供预编译的4KB和64KB页大小内核。

RHEL 9配置步骤

  1. 安装64K内核包:dnf –y install kernel-64k
  2. 设置为默认启动内核:
    1
    2
    
    k=$(echo /boot/vmlinuz*64k)
    grubby --set-default=$k --update-kernel=$k --args="crashkernel=2G-:640M"
    

Ubuntu 22.04配置

  1. 安装arm64+largemem ISO或sudo apt install linux-generic-64K
  2. 设置64K内核为默认:
    1
    
    echo "GRUB_FLAVOUR_ORDER=generic-64k" | sudo tee /etc/default/grub.d/local-order.cfg
    

Oracle Linux配置

  1. 安装内核包:sudo dnf install -y kernel-uek64k
  2. 设置为默认:sudo grubby --set-default=$(echo /boot/vmlinuz*64k)

自定义编译内核时,可通过make menuconfig在"Processor type and features"子菜单中修改ARM64 CPU特性寄存器配置,或直接修改.config文件中的CONFIG_ARM_PAGE_SHIFT值(12对应4K,14对应16K,16对应64K)。

使用getconf PAGESIZE命令可验证当前内核的页大小设置,64K系统将显示65536。

结论

调整云系统的内核内存页大小可显著提升许多常见云工作负载的应用性能。对于包含大量磁盘、内存或网络I/O的应用程序,在ARM主机上使用16K或64K页内核可能带来显著改进。

但这不是万能方案,实际效果可能因应用而异。建议同时使用合成基准测试和真实场景测试来验证页大小改变的影响。多数支持Arm64的Linux发行版已在其仓库中包含多种内核,安装这些内核包并启动测试的成本相对较低。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计