使用 Arm64 原子操作诊断和修复页面错误性能问题

主要观点:在运行预缓存的合成基准测试时,发现安培 CPU 存在异常性能影响,其页面错误比 x86 CPU 多,原因是特定原子指令(如 ldadd)在某些条件下会触发两个“页面错误”,影响了内存管理和性能。
关键信息:

  • 合成基准测试用于预热缓存,发现安培 CPU 性能受影响,通过分析发现是原子指令导致页面错误增多。
  • 内存管理方面,操作系统为用户空间程序创建虚拟内存地址空间,Linux 有透明大页(THP)功能,页面错误分为读错误和写错误。
  • 原子指令在 Arm64 上使用 LSE 家族指令,单个原子指令会触发读和写两个页面错误,在使用 2M 大透明大页时影响更明显。
  • 解决问题的方法有使用madvise()系统调用避免原子指令和内存预热的交互,以及与 Linux 内核社区合作确保写错误分配大页等。
    重要细节:
  • 例如 OpenJDK 用原子添加指令预触内存,通过分析基准测试在安培和 x86 CPU 上的表现,发现安培 CPU 的页面错误数高且透明大页会碎片化。
  • Arm64 上的 LSE 原子指令在单个指令中执行加载、修改和存储操作,与内存管理子系统交互导致两个页面错误。
  • 对于内存预热,更新 JVM 行为用madvise(addr, len, MADV_POPULATE_WRITE)避免原子指令和内存预热的交互,但此功能在 Linux 内核 5.14 才添加。
  • 正在与 Linux 内核社区合作确保使用 THP 时写错误分配大页,目前此问题未完全解决,内核社区在努力修复,同时讨论如何改进原子“读-修改-写”指令以减少页面错误。
阅读 15
0 条评论