主要观点:在运行预缓存的合成基准测试时,发现安培 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 时写错误分配大页,目前此问题未完全解决,内核社区在努力修复,同时讨论如何改进原子“读-修改-写”指令以减少页面错误。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。