为什么在 Raspberry pi 上 Open 和 Oracle JDK 之间存在如此大的性能差异?

在我的Raspberry上,我用两个JVM做了一些性能测试,如CaffeineMark和SciMark。即使我听说差异非常小,它们之间也存在巨大的性能差异。我还尝试使用浮点数进行计算,并且Oracle JDK获得了更好的分数,即使两者都应该支持硬浮点abi。

我用作操作系统。Linux raspberrypi 3.18.11-v7+

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在处理浮点数上的性能。

OpenJDK: 257ms
OracleJDK: 151ms

0.1 到 1200000 的步骤:

OpenJDK: 457ms
OracleJDK: 263ms

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编译器,但结果没有不同。


答案 1

OpenJDK Zero VM 是一个仅解释器的 JVM。一方面,它更容易移植,因为它没有特定于体系结构的汇编代码,但另一方面,它没有性能,因为它没有特定于体系结构的汇编代码。

OracleJDK 利用了平台的浮点 ABI(RP1 上的软浮点和 RP2 上的硬浮点)。我可以想象它有相当多的汇编代码,特定于ARM架构,这就是为什么它得分更高。

一个名为Shark的JIT编译器,基于LLVM,很早就在OpenJDK Zero VM中引入。我不确定你的系统的OpenJDK是否是用Shark构建的,但它可能是。它提供了在没有汇编代码和仍然运行高效本机代码之间的折衷方案。如果未启用Shark,则在启用Shark的情况下构建IcedTea将提高性能。如果启用了Shark,那么这就是OpenJDK不那么糟糕的原因。


答案 2

2018 年 4 月的更新。

我在Raspberry Pi 3上使用Raspbian Stretch运行Java Whetstone离线基准测试。源代码可以在文件中找到。Raspberry_Pi_Benchmarks/java/source code/whetstone-off-line/whetstc.java

结论是openjdk-9-jre比openjdk-8-jre(测试版本1.8.0_162)更快,后者又比oracle-java8-jdk(测试版本1.8.0_65)更快。还要注意,我使用了一个带有oracle-java8-jdk的旧内核。

openjdk-9-jdk from Raspbian repos:

$ 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 from Raspbian repos:

$ 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 from Raspbian repos:

$ 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

推荐