为什么 Open 和 Oracle JDK 在 Raspberry pi 上存在如此大的性能差异?
Why is there such a performance difference on Raspberry pi between Open and Oracle JDK?
在我的 Raspberry 上,我用两个 JVM 做了一些性能测试,比如 CaffeineMark 和 SciMark。尽管我听说差异很小,但它们之间存在巨大的性能差异。我还尝试使用浮点数进行计算,Oracle JDK 得到了更好的分数,尽管两者都应该支持硬浮点 abi。
我用Linux raspberrypi 3.18.11-v7+
作为OS。
OpenJDK:
java version "1.7.0_79"
OpenJDK Runtime Environment (IcedTea 2.5.5) (7u79-2.5.5-1~deb7u1+rpi1)
OpenJDK Zero VM (build 24.79-b02, mixed mode)
OracleJDK:
java version "1.7.0_40"
Java(TM) SE Runtime Environment (build 1.7.0_40-b43)
Java HotSpot(TM) Client VM (build 24.0-b56, mixed mode)
SciMark results:
OpenJDK OracleJDK
Composite Score 14.280735577363213 || 32.24948180361924
FFT (1024) 9.482866845055302 || 26.447121360843663
SOR (100x100) 27.14938943220646 || 59.68022533004399
Monte Carlo 3.6298604956147384 || 10.561671865446971
Sparse matmult 15.603809523809524 || 26.64931580928407
LU (100x100) 15.53775159013005 || 37.90907465247749
我使用了一个以 0.1 步为单位计算浮点数到 600000 的程序。我试图测试 JVM 在处理浮点数方面的性能。
打开JDK:257ms
甲骨文JDK:151 毫秒
0.1 步到 1200000:
打开JDK:457ms
甲骨文JDK:263 毫秒
public class Testing {
/**
* @param args
*/
public static long Test()
{
float counter=0.0f;
long startTime = System.currentTimeMillis();
while (counter <= 1_200_000.0f)
{
counter += 0.1f;
}
return System.currentTimeMillis() - startTime;
}
public static void main(String[] args){
System.out.println(Test());
}
}
我尝试了 SlipperySeal 中提到的增强功能并将测试放入循环中。我也尝试过使用c2编译器,但结果没有什么不同。
OpenJDK 零虚拟机是一个只有解释器的 JVM。一方面,它更容易移植,因为它没有特定于体系结构的汇编代码,但另一方面,它的性能不佳,因为它没有特定于体系结构的汇编代码。
OracleJDK 利用平台的浮点 ABI(RP1 上的软浮点和 RP2 上的硬浮点)。我可以想象它有相当多的汇编代码,特定于 ARM 架构,这就是它得分更高的原因。
早期在OpenJDK Zero VM中引入了一个基于LLVM的名为Shark的JIT编译器。我不确定您系统的 OpenJDK 是否是使用 Shark 构建的,但它可能是。它在没有汇编代码和仍然 运行 高效的本机代码之间提供了折衷。如果未启用 Shark,则在启用 Shark 的情况下构建 IcedTea 将提高性能。如果启用了 Shark,这就是 OpenJDK 没有那么糟糕的原因。
2018 年 4 月更新。
我 运行 Java Whetstone 离线基准测试 Raspberry Pi 3 Raspbian Stretch。可以在文件 Raspberry_Pi_Benchmarks/java/source code/whetstone-off-line/whetstc.java
.
中找到源代码 here
结论是openjdk-9-jre比openjdk-8-jre(测试版本1.8.0_162)快,后者又比openjdk-8-jre快oracle-java8-jdk(测试版本 1.8.0_65)。另请注意,我使用了带有 oracle-java8-jdk.
的旧内核
openjdk-9-jdk 来自 Raspbian 回购:
$ java -version
openjdk version "9-Raspbian"
OpenJDK Runtime Environment (build 9-Raspbian+0-9b181-4bpo9rpt1)
OpenJDK Server VM (build 9-Raspbian+0-9b181-4bpo9rpt1, mixed mode)
$ java whetstc
Whetstone Benchmark Java Version, apr. 26 2018, 23:15:40
1 Pass
Test Result MFLOPS MOPS millisecs
N1 floating point -1,124750137 333,22 0,0576
N2 floating point -1,131330490 293,19 0,4584
N3 if then else 1,000000000 185,95 0,5566
N4 fixed point 12,000000000 412,95 0,7628
N5 sin,cos etc. 0,499110132 22,40 3,7140
N6 floating point 0,999999821 212,70 2,5360
N7 assignments 3,000000000 105,66 1,7490
N8 exp,sqrt etc. 0,825148463 16,70 2,2280
MWIPS 829,02 12,0624
Operating System Linux, Arch. arm, Version 4.14.34-v7+
Java Vendor Oracle Corporation, Version 9-Raspbian
CPU null
openjdk-8-jdk 来自 Raspbian 回购:
$ java -version
openjdk version "1.8.0_162"
OpenJDK Runtime Environment (build 1.8.0_162-8u162-b12-1~deb9u1-b12)
OpenJDK Client VM (build 25.162-b12, mixed mode)
$ java whetstc
Whetstone Benchmark Java Version, Apr 27 2018, 13:13:26
1 Pass
Test Result MFLOPS MOPS millisecs
N1 floating point -1.124750137 181.82 0.1056
N2 floating point -1.131330490 175.92 0.7640
N3 if then else 1.000000000 88.61 1.1680
N4 fixed point 12.000000000 389.85 0.8080
N5 sin,cos etc. 0.499110132 9.35 8.8980
N6 floating point 0.999999821 76.27 7.0720
N7 assignments 3.000000000 275.82 0.6700
N8 exp,sqrt etc. 0.825148463 7.15 5.2060
MWIPS 405.00 24.6916
Operating System Linux, Arch. arm, Version 4.14.34-v7+
Java Vendor Oracle Corporation, Version 1.8.0_162
CPU null
oracle-java8-jdk 来自 Raspbian 回购:
$ java -version
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) Client VM (build 25.65-b01, mixed mode)`
$ java whetstc
Whetstone Benchmark Java Version, Nov 15 2017, 11:16:37
1 Pass
Test Result MFLOPS MOPS millisecs
N1 floating point -1.124750137 91.52 0.2098
N2 floating point -1.131330490 89.01 1.5100
N3 if then else 1.000000000 44.27 2.3380
N4 fixed point 12.000000000 229.76 1.3710
N5 sin,cos etc. 0.499110103 3.01 27.6400
N6 floating point 0.999999821 44.95 12.0000
N7 assignments 3.000000000 137.09 1.3480
N8 exp,sqrt etc. 0.751108646 0.58 63.9100
MWIPS 90.64 110.3268
Operating System Linux, Arch. arm, Version 4.9.35-v7+
Java Vendor Oracle Corporation, Version 1.8.0_65
CPU null
在我的 Raspberry 上,我用两个 JVM 做了一些性能测试,比如 CaffeineMark 和 SciMark。尽管我听说差异很小,但它们之间存在巨大的性能差异。我还尝试使用浮点数进行计算,Oracle JDK 得到了更好的分数,尽管两者都应该支持硬浮点 abi。
我用Linux raspberrypi 3.18.11-v7+
作为OS。
OpenJDK:
java version "1.7.0_79"
OpenJDK Runtime Environment (IcedTea 2.5.5) (7u79-2.5.5-1~deb7u1+rpi1)
OpenJDK Zero VM (build 24.79-b02, mixed mode)
OracleJDK:
java version "1.7.0_40"
Java(TM) SE Runtime Environment (build 1.7.0_40-b43)
Java HotSpot(TM) Client VM (build 24.0-b56, mixed mode)
SciMark results:
OpenJDK OracleJDK
Composite Score 14.280735577363213 || 32.24948180361924
FFT (1024) 9.482866845055302 || 26.447121360843663
SOR (100x100) 27.14938943220646 || 59.68022533004399
Monte Carlo 3.6298604956147384 || 10.561671865446971
Sparse matmult 15.603809523809524 || 26.64931580928407
LU (100x100) 15.53775159013005 || 37.90907465247749
我使用了一个以 0.1 步为单位计算浮点数到 600000 的程序。我试图测试 JVM 在处理浮点数方面的性能。
打开JDK:257ms
甲骨文JDK:151 毫秒
0.1 步到 1200000:
打开JDK:457ms
甲骨文JDK:263 毫秒
public class Testing {
/**
* @param args
*/
public static long Test()
{
float counter=0.0f;
long startTime = System.currentTimeMillis();
while (counter <= 1_200_000.0f)
{
counter += 0.1f;
}
return System.currentTimeMillis() - startTime;
}
public static void main(String[] args){
System.out.println(Test());
}
}
我尝试了 SlipperySeal 中提到的增强功能并将测试放入循环中。我也尝试过使用c2编译器,但结果没有什么不同。
OpenJDK 零虚拟机是一个只有解释器的 JVM。一方面,它更容易移植,因为它没有特定于体系结构的汇编代码,但另一方面,它的性能不佳,因为它没有特定于体系结构的汇编代码。
OracleJDK 利用平台的浮点 ABI(RP1 上的软浮点和 RP2 上的硬浮点)。我可以想象它有相当多的汇编代码,特定于 ARM 架构,这就是它得分更高的原因。
早期在OpenJDK Zero VM中引入了一个基于LLVM的名为Shark的JIT编译器。我不确定您系统的 OpenJDK 是否是使用 Shark 构建的,但它可能是。它在没有汇编代码和仍然 运行 高效的本机代码之间提供了折衷。如果未启用 Shark,则在启用 Shark 的情况下构建 IcedTea 将提高性能。如果启用了 Shark,这就是 OpenJDK 没有那么糟糕的原因。
2018 年 4 月更新。
我 运行 Java Whetstone 离线基准测试 Raspberry Pi 3 Raspbian Stretch。可以在文件 Raspberry_Pi_Benchmarks/java/source code/whetstone-off-line/whetstc.java
.
结论是openjdk-9-jre比openjdk-8-jre(测试版本1.8.0_162)快,后者又比openjdk-8-jre快oracle-java8-jdk(测试版本 1.8.0_65)。另请注意,我使用了带有 oracle-java8-jdk.
的旧内核openjdk-9-jdk 来自 Raspbian 回购:
$ java -version
openjdk version "9-Raspbian"
OpenJDK Runtime Environment (build 9-Raspbian+0-9b181-4bpo9rpt1)
OpenJDK Server VM (build 9-Raspbian+0-9b181-4bpo9rpt1, mixed mode)
$ java whetstc
Whetstone Benchmark Java Version, apr. 26 2018, 23:15:40
1 Pass
Test Result MFLOPS MOPS millisecs
N1 floating point -1,124750137 333,22 0,0576
N2 floating point -1,131330490 293,19 0,4584
N3 if then else 1,000000000 185,95 0,5566
N4 fixed point 12,000000000 412,95 0,7628
N5 sin,cos etc. 0,499110132 22,40 3,7140
N6 floating point 0,999999821 212,70 2,5360
N7 assignments 3,000000000 105,66 1,7490
N8 exp,sqrt etc. 0,825148463 16,70 2,2280
MWIPS 829,02 12,0624
Operating System Linux, Arch. arm, Version 4.14.34-v7+
Java Vendor Oracle Corporation, Version 9-Raspbian
CPU null
openjdk-8-jdk 来自 Raspbian 回购:
$ java -version
openjdk version "1.8.0_162"
OpenJDK Runtime Environment (build 1.8.0_162-8u162-b12-1~deb9u1-b12)
OpenJDK Client VM (build 25.162-b12, mixed mode)
$ java whetstc
Whetstone Benchmark Java Version, Apr 27 2018, 13:13:26
1 Pass
Test Result MFLOPS MOPS millisecs
N1 floating point -1.124750137 181.82 0.1056
N2 floating point -1.131330490 175.92 0.7640
N3 if then else 1.000000000 88.61 1.1680
N4 fixed point 12.000000000 389.85 0.8080
N5 sin,cos etc. 0.499110132 9.35 8.8980
N6 floating point 0.999999821 76.27 7.0720
N7 assignments 3.000000000 275.82 0.6700
N8 exp,sqrt etc. 0.825148463 7.15 5.2060
MWIPS 405.00 24.6916
Operating System Linux, Arch. arm, Version 4.14.34-v7+
Java Vendor Oracle Corporation, Version 1.8.0_162
CPU null
oracle-java8-jdk 来自 Raspbian 回购:
$ java -version
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) Client VM (build 25.65-b01, mixed mode)`
$ java whetstc
Whetstone Benchmark Java Version, Nov 15 2017, 11:16:37
1 Pass
Test Result MFLOPS MOPS millisecs
N1 floating point -1.124750137 91.52 0.2098
N2 floating point -1.131330490 89.01 1.5100
N3 if then else 1.000000000 44.27 2.3380
N4 fixed point 12.000000000 229.76 1.3710
N5 sin,cos etc. 0.499110103 3.01 27.6400
N6 floating point 0.999999821 44.95 12.0000
N7 assignments 3.000000000 137.09 1.3480
N8 exp,sqrt etc. 0.751108646 0.58 63.9100
MWIPS 90.64 110.3268
Operating System Linux, Arch. arm, Version 4.9.35-v7+
Java Vendor Oracle Corporation, Version 1.8.0_65
CPU null