麦斯科技 · 2021年11月09日

提高OCI Ampere A1计算实例上的Java性能

https://community.arm.com/arm-community-blogs/b/tools-software-ides-blog/posts/performance-of-specjbb2015-on-oci-ampere-a1-compute-instances

黄诗友 2021年11月3日

介绍

Oracle云基础设施(OCI)最近推出了基于Arm Neoverse N1的虚拟机和裸机实例的Ampere A1 Compute系列。这些A1实例使用Ampere Altra CPU,专门为云应用程序提供性能、可扩展性和安全性而设计。A1 Flex VM系列支持海量的VM Shapes,可配置1-80个内核和1-512GB RAM(每个内核最多64GB)。Ampere A1 compute还提供裸金属配置,每个实例多至2-sockets和160-cores。

在本博客中,我们研究了在OCI A1实例上使用SPECjbb2015[1]的Java性能。通过参考在线SPECjbb提交使用的配置,我们优化了SPECjbb2015以获得最佳性能。由于堆大小非常大和其他原因,这些Java选项可能不适用于所有Java工作负载。这里的目标是使SPECjbb在A1上可以获得的最佳分数。我们比较了SPECjbb2015在不同版本OpenJDK上的性能结果,以确定提高性能的补丁列表。由于SPECjbb是一个对延迟敏感的工作负载,我们在本博客中还介绍了Arm LSE(大型系统扩展)对性能的影响。我们自己从源代码构建OpenJDK,所有测试都基于以下环境:

BM.Standard.A1.160:基于Arm Neoverse N1核的Ampere® Altra® CPUs,最大支持3.0GHz全核。每个核都有自己的64KB一级I-cache、64KB一级D-cache和1MB二级D-cache。

SPECjbb2015是一个从头开始开发的基准测试,用于测量Java服务器性能:

“SPECjbb2015基准测试基于一家全球超市公司的使用模型,其IT基础设施处理销售点请求、在线购买和数据挖掘操作。它使用最新的数据格式(XML)、使用压缩的通信和安全消息传递,使用Java 7和更高版本的功能。”。

此基准测试提供了两个评估JVM性能的指标:与吞吐量相关的max-jOPS 和与服务级别协议(SLA)下的关键吞吐量相关的critical-jOPS,响应时间从10到100毫秒不等。

默认配置和优化配置之间SPECjbb2015分数的比较

SPECjbb2015可以在三种模式下进行测试:Composite, MultiJVM和Distributed。在我们的评估中,我们使用了Composite,即使用单个JVM来运行工作负载。所有测试都是在Oracle-Linux-8上运行的,通过设置numactl--membind=0-c0-79,有80个内核的BM.Standard.A1.160。我们首先使用现成的默认设置运行SPECjbb,以获得基线性能。然后,我们调整了Java flags,试图在A1上获得最佳的max-jOPS和critical-jOPS。

我们最初的Java flags是从两个公开的在线SPECjbb2015提交文件中借用的[2,3]。我们根据硬件的核心计数相应地调整了flags,并删除了与Arm架构无关的flags,例如:-XX:UseAVX。由于我们在测试中只使用了单个NUMA域中的内核,因此我们还删除了在本例中没有影响的flags,例如-XX:+UseNUMA。

在我们的评估中,我们使用了以下Java flags:

-server -Xms124g -Xmx124g -Xmn114g -XX:SurvivorRatio=20 -XX:MaxTenuringThreshold=15 -XX:+UseLargePages -XX:LargePageSizeInBytes=2m -XX:+UseParallelGC -XX:+AlwaysPreTouch -XX:-UseAdaptiveSizePolicy -XX:-UsePerfData -XX:ParallelGCThreads=40 -XX:+UseTransparentHugePages -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=32

SPECjbb2015属性:

-Dspecjbb.comm.connect.timeouts.connect=700000 -Dspecjbb.comm.connect.timeouts.read=700000

-Dspecjbb.comm.connect.timeouts.write=700000 -Dspecjbb.customerDriver.threads.probe=80

-Dspecjbb.forkjoin.workers.Tier1=80 -Dspecjbb.forkjoin.workers.Tier2=1 -Dspecjbb.forkjoin.workers.Tier3=16

-Dspecjbb.heartbeat.period=100000 -Dspecjbb.heartbeat.threshold=1000000

OS设置:

echo always > /sys/kernel/mm/transparent_hugepage/enabled

echo always > /sys/kernel/mm/transparent_hugepage/defrag

图1比较了使用默认设置和优化配置的性能分数

Java-Perf-Fig1-JPG.jpg

图1。SPECjbb2015使用基本设置与优化设置的分数

我们使用GCC10构建OpenJDK-11.0.12-ga,并选择“-mno-outline-atomics”。使用此版本的OpenJDK优化配置的最佳max-jOPS为122074,比基线得分92973提高了近31%。critical-jOPS从72171提高到47729,提高51%。

请注意,我们使用的优化配置用于实现更高的max-jOPS和critical-jOPS。考虑到具有巨大堆大小和大型对象对齐的设置,它们可能不适用于所有Java工作负载,这对于生产运行来说是不现实的。

SPECjbb2015在不同版本的OpenJDK上得分

我们还对各种不同版本的OpenJDK进行了基准测试,以了解这些补丁的性能变化。

Java-Perf-Fig2-JPG.jpg

图2。使用优化配置的OpenJDK11到16上的SPECjbb分数

图2显示了使用优化配置的OpenJDK 11到16的GA版本的SPECjbb分数。总的来说,从JDK11到JDK16,max-jOPS的变化不大。jdk-11.0.12-ga上最低的max-jOPS 分值为122074,jdk-14-ga上最高的max-jOPS 分值为127957。critical-jOPS分值从72171提高到97810,升幅为35.5%。主要的改进归功于JDK11到JDK14之间的补丁。

LSE对Java性能的影响

Arm在Armv8.1中引入了 Large System Extensions (LSE),它提供了一组原子操作,如compare-and-swap(CAS)、atomic load and increment(LDADD)。大多数新操作都具有load-acquire或store-release语义,与通过成对的load/store独占实现原子操作的传统方式相比,这是一种低成本的原子操作。在我们的实验中,我们发现LSE有利于高度并发和使用大量同步的工作负载。我们通过运行使用或不使用LSE编译的JDK来评估LSE对Java性能的影响。用户可以通过在-march选项中添加GCC flags+LSE来使用LSE构建二进制文件。要使二进制文件在任何Arm v8系统上运行(其中一些可能不支持LSE),用户可以在编译时添加编译器flags -moutline atomics。此flags在GCC 9.4中引入,并在GCC 10中默认启用。当GCC使用此flags编译软件时,它会自动生成代码以动态检查是否支持LSE。在我们的定向测试中,由于动态检查,我们可以忽略性能开销。

我们使用更常见的JVM堆大小“-Xmx30g-Xms2g”评估了LSE的影响,并使用了G1GC,JDK11中的默认GC。尽管我们使用此设置实现了略低的max-jOPS和critical-jOPS,但此设置对于真实的Java应用程序更为现实。以下是新的Java flags:

-server -XX:+UseG1GC -Xmx30g -Xms2g -XX:NewSize=1332k -XX:MaxNewSize=18g -XX:GCTimeRatio=19 -XX:-InlineSynchronizedMethods -XX:+LoopUnswitching -XX:-OptimizeFill -XX:+UseSignalChaining

图3比较了启用LSE对OpenJDK11的两个版本的影响,即11.0.8-ga和11.0.12-ga。

1464.Java Perf Fig3a v3.png-1040x480.png

图3。LSE对SPECjbb2015性能的影响

左边的图表显示了LSE指令在max-jOPS和critical-jOPS上带来的巨大改进。使用JDK-11.0.8-ga,max-jOPS 和critical-jOPS分别提高了77.9%和109.9%。而右边的JDK-11.0.12-ga图表显示,LSE仅将critical-jOPS提升了5%,max-jOPS甚至略有下降。由于JDK-11.0.8-ga和JDK-11.0.12-ga这两个子版本之间只有很小的变化,令人惊讶的是,它们表现出完全不同的性能,特别是在SLA相关分数上。我们调查了两个版本之间的变化,以隔离导致性能差距的补丁。我们发现补丁JDK-8248214[4]导致了本例中的差异。此修补程序通过在两个并排声明的volatile变量之间添加paddings 来减少错误共享缓存争用。OpenJDK-11.0.9及更高版本修复了该问题。这一发现提供了很好的证据,表明LSE对于竞争激烈的工作负载的性能非常重要。

结论

在本博客中,我们在OCI Ampere A1计算实例上使用SPECjbb2015评估了Java性能。我们比较了SPECjbb2015在有和没有优化配置的情况下的性能分数。它显示了我们的调优设置在OpenJDK-11.0.12-ga上分别将max-jOPS和critical-jOPS提高了30%和59%。我们在11到16两个不同的OpenJDK版本上测试了SPECjbb2015。尽管在较新版本的OpenJDK上,max-jOPS并没有太大改进,但critical-jOPS从JDK11到JDK16的性能提高了35%。我们还使用更常见的Java堆大小和JDK的默认GC评估了LSE对性能的影响。我们的主要发现是,LSE对于竞争激烈的工作负载至关重要

参考
[1] https://www.spec.org/jbb2015

[2] https://www.spec.org/jbb2015/results/res2020q2/jbb2015-20200416-00540.html

[3] https://www.spec.org/jbb2015/results/res2019q2/jbb2015-20190313-00350.html

[4] https://bugs.openjdk.java.net/browse/JDK-8248214

推荐阅读
关注数
5758
内容数
525
定期发布Arm相关软件信息,微信公众号 ArmSWDevs,欢迎关注~
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息