Warum läuft dieser einfache und kleine Java-Code in allen Graal-JVMs 30x schneller, aber nicht auf allen Oracle-JVMs?Java

Java-Forum
Guest
 Warum läuft dieser einfache und kleine Java-Code in allen Graal-JVMs 30x schneller, aber nicht auf allen Oracle-JVMs?

Post by Guest »

Ich kompiliere nichts nach native, mit anderen Worten, ich verwende nicht native-image von GraalVM. Ich führe einfach dieselbe Java-Klasse (gleicher Java-Bytecode) mit GraalVM und dann dieselbe Java-Klasse (gleicher Java-Bytecode) mit regulären Oracle-JVMs aus.
Es spielt keine Rolle, welche Version von Java, das ich verwende, oder Plattform (ich habe es unter Linux und Mac getestet). GraalVM ist immer viel schneller (30x) als jede andere reguläre JVM.
Es sieht so aus, als würden die regulären JVMs die Methode mit ihrem JIT nicht richtig optimieren. Beachten Sie, dass die Methode sehr einfach und klein ist.
Hat jemand eine Ahnung, warum das so ist und wie ich das in meiner regulären JVM beheben könnte? Die einzige Problemumgehung besteht derzeit in der Migration zu GraalVM. Es ist sehr einfach, den folgenden Code zu kompilieren und auszuführen, um das Problem zu reproduzieren. Kompilieren Sie einfach und führen Sie es dann zuerst mit einer Oracle-JVM und dann mit einer beliebigen Graal-JVM aus, um den Unterschied zu sehen.

Code: Select all

public class OracleJvm23MathBug {

// simple and small amount of math
// =====> should be optimized/compiled/inlined for sure!
private static final long doSomething(int load, int i) {
long x = 0;
for (int j = 0; j < load; j++) {
long pow = (i % 8) * (i % 16);
if (i % 2 == 0) {
x += pow;
} else {
x -= pow;
}
}
return x;
}

/*
* Execute this with OpenJDK/Zulu/Oracle JVM 23 => average 215 nanoseconds
* Now execute this with Graal23 JVM 23 => average 7 nanoseconds
*
* This bug can be observed in any platform (I tested on Linux and Mac)
*
* $ java -version
* java version "23.0.1" 2024-10-15
* Java(TM) SE Runtime Environment (build 23.0.1+11-39)
* Java HotSpot(TM) 64-Bit Server VM (build 23.0.1+11-39, mixed mode, sharing)
*
* $ java -cp . OracleJvm23MathBug
* Value computed: -550000000000
* Measurements: 10000000| Avg Time: 215 nanos | Min Time: 83 nanos | Max Time: 199750 nanos
*
* $ java -version
* java version "23.0.1" 2024-10-15
* Java(TM) SE Runtime Environment Oracle GraalVM 23.0.1+11.1 (build 23.0.1+11-jvmci-b01)
* Java HotSpot(TM) 64-Bit Server VM Oracle GraalVM 23.0.1+11.1 (build 23.0.1+11-jvmci-b01, mixed mode, sharing)
*
* $ java -cp .  OracleJvm23MathBug
* Value computed: -550000000000
* Measurements: 10000000| Avg Time: 7 nanos | Min Time: 0 nanos | Max Time: 178625 nanos
*/
public static final void main(String[] args) {
final int iterations = 10_000_000;
final int load = 10_000;
NanoBench bench = new NanoBench();
long computed = 0;
for (int i = 0; i < iterations; i++) {
bench.mark();
computed += doSomething(load, i);
bench.measure();
}
System.out.println("Value computed: " + computed);
bench.printResults();
}

private static class NanoBench {

private int measurements;
private long totalTime, minTime, maxTime, time;
private final StringBuilder sb = new StringBuilder(128);

NanoBench() {
reset();
}

public final void reset() {
totalTime = time = measurements = 0;
maxTime = Long.MIN_VALUE;
minTime = Long.MAX_VALUE;
}

public final void mark() {
time = System.nanoTime();
}

public final void measure() {
long lastNanoTime = System.nanoTime() - time;
totalTime += lastNanoTime;
minTime = lastNanoTime < minTime ? lastNanoTime : minTime;
maxTime = lastNanoTime > maxTime ? lastNanoTime : maxTime;
measurements++;
}

public final void printResults() {
sb.setLength(0);
sb.append("Measurements: ").append(measurements);
sb.append("| Avg Time: ").append((long) (totalTime / (double) measurements)).append(" nanos");
sb.append(" | Min Time: ").append(minTime).append(" nanos");
sb.append(" | Max Time: ").append(maxTime).append(" nanos\n\n");
for (int i = 0; i < sb.length(); i++) System.out.print(sb.charAt(i));
}
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post