Skip to content

Commit

Permalink
Refactor funccall benchmark
Browse files Browse the repository at this point in the history
  • Loading branch information
YaSuenag committed Apr 30, 2024
1 parent 9a4dd5b commit fff651f
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 21 deletions.
50 changes: 40 additions & 10 deletions benchmarks/funccall/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,52 @@ This benchmark runs RDTSC instruction. JNI function is written in assembly code

# How to build

```sh
$ cd /path/to/ffasm
$ mvn install
$ cd benchmark/funccall
$ mvn package
```
cd /path/to/ffasm
mvn install
cd benchmark/funccall
mvn package
```

# Check result from RDTSC

```sh
$ mvn exec:exec@single-run
```
mvn exec:exec@single-run
```

# Run benchmark

```sh
$ cd target
$ $JAVA_HOME/bin/java -jar ffmasm-benchmark-funccall-1.0.3.jar
```
cd target
$JAVA_HOME/bin/java -jar ffmasm-benchmark-funccall-1.0.3.jar
```

JIT log ( `-Xlog:jit+compilation=debug,jit+inlining=debug` ) would be collected into `target` dir with PID.

# Run single benchmark

You can use [measure-single-benchmark.sh](measure-single-benchmark.sh) to run single benchmark.
Benchmark should be set from following list:

* FFM
* FFMCritical
* RegisterNatives
* JNI

JIT log ( `-Xlog:jit+compilation=debug,jit+inlining=debug` ) would be collected into `target` dir with benchmark name.

## Measures iterations or execution time

```
./measure-single-benchmark.sh run [benchmark]
```

## Measure iterations or execution time with `perf`

You have to install perf tool before running.

```
./measure-single-benchmark.sh perf [benchmark]
```

`perf.data` would be stored into working directory.
21 changes: 21 additions & 0 deletions benchmarks/funccall/measure-single-benchmark.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

MODE=$1
BENCH=$2
BASEDIR=$(dirname $0)

EXECUTABLE=$JAVA_HOME/bin/java
FUNCCALL_JAR=`ls $BASEDIR/target/original-ffmasm-benchmark-funccall-*.jar`
FFMASM_JAR=`ls $HOME/.m2/repository/com/yasuenag/ffmasm/*-SNAPSHOT/ffmasm-*-SNAPSHOT.jar | tail -n 1`

JVM_OPTS="-cp $FUNCCALL_JAR:$FFMASM_JAR -Djava.library.path=$BASEDIR/target --enable-native-access=ALL-UNNAMED -Xms4g -Xmx4g -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -XX:+AlwaysPreTouch -XX:+PreserveFramePointer -Xlog:jit+compilation=debug,jit+inlining=debug:file=$BASEDIR/target/$BENCH-jit.log::filesize=0"
APP_OPTS="com.yasuenag.ffmasm.benchmark.funccall.FuncCallComparison iterate $BENCH"

if [ "$MODE" = "perf" ]; then
JVM_OPTS="$JVM_OPTS -XX:+UnlockDiagnosticVMOptions -XX:+DumpPerfMapAtExit"
exec perf record -g -F 99 -- $EXECUTABLE $JVM_OPTS $APP_OPTS
elif [ "$MODE" = "run" ]; then
exec $EXECUTABLE $JVM_OPTS $APP_OPTS
else
echo 'Unknown mode'
fi
1 change: 1 addition & 0 deletions benchmarks/funccall/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
<argument>-Djava.library.path=.</argument>
<argument>--enable-native-access=ALL-UNNAMED</argument>
<argument>com.yasuenag.ffmasm.benchmark.funccall.FuncCallComparison</argument>
<argument>single</argument>
</arguments>
</configuration>
</execution>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.lang.invoke.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;

import com.yasuenag.ffmasm.*;
import com.yasuenag.ffmasm.amd64.*;
Expand All @@ -13,8 +14,8 @@

@State(Scope.Benchmark)
@BenchmarkMode(Mode.Throughput)
@Fork(value = 1, jvmArgsAppend = {"--enable-native-access=ALL-UNNAMED", "-Djava.library.path=.", "-Xms4g", "-Xmx4g", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseEpsilonGC", "-XX:+AlwaysPreTouch"})
@Warmup(iterations = 1, time = 3, timeUnit = TimeUnit.SECONDS)
@Fork(value = 1, jvmArgsAppend = {"--enable-native-access=ALL-UNNAMED", "-Djava.library.path=.", "-Xms4g", "-Xmx4g", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseEpsilonGC", "-XX:+AlwaysPreTouch", "-XX:+PreserveFramePointer", "-Xlog:jit+compilation=debug,jit+inlining=debug:file=jit%p.log::filesize=0"})
@Warmup(iterations = 1, time = 10, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 3, time = 10, timeUnit = TimeUnit.SECONDS)
public class FuncCallComparison{

Expand Down Expand Up @@ -57,7 +58,7 @@ public void setup(){
@Benchmark
public long invokeFFMRDTSC(){
try{
return (long)ffmRDTSC.invoke();
return (long)ffmRDTSC.invokeExact();
}
catch(Throwable t){
throw new RuntimeException(t);
Expand All @@ -67,7 +68,7 @@ public long invokeFFMRDTSC(){
@Benchmark
public long invokeFFMRDTSCCritical(){
try{
return (long)ffmRDTSCCritical.invoke();
return (long)ffmRDTSCCritical.invokeExact();
}
catch(Throwable t){
throw new RuntimeException(t);
Expand All @@ -87,18 +88,75 @@ public void tearDown(){
}
}

public static void main(String[] args){
var inst = new FuncCallComparison();
inst.setup();
long nativeVal = inst.invokeJNI();
long ffmVal = inst.invokeFFMRDTSC();
long ffmCriticalVal = inst.invokeFFMRDTSCCritical();
long ffmRegisterNativesVal = inst.invokeFFMRDTSCRegisterNatives();
public void singleRun(){
long nativeVal = invokeJNI();
long ffmVal = invokeFFMRDTSC();
long ffmCriticalVal = invokeFFMRDTSCCritical();
long ffmRegisterNativesVal = invokeFFMRDTSCRegisterNatives();

System.out.println(" JNI: " + nativeVal);
System.out.println(" FFM: " + ffmVal);
System.out.println(" FFM (Critical): " + ffmCriticalVal);
System.out.println("FFM (RegisterNatives): " + ffmRegisterNativesVal);
}

public void iterate(String benchmark){
Runnable runner = switch(benchmark){
case "JNI" -> this::invokeJNI;
case "FFM" -> this::invokeFFMRDTSC;
case "FFMCritical" -> this::invokeFFMRDTSCCritical;
case "RegisterNatives" -> this::invokeFFMRDTSCRegisterNatives;
default -> throw new IllegalArgumentException("Unknown benchmark");
};

final AtomicLong counter = new AtomicLong();

var task = new TimerTask(){
@Override
public void run(){
System.out.printf("Interrupted: counter = %d\n", counter.get());
System.exit(0);
}
};
var timer = new Timer("Benchmark Finisher");
timer.schedule(task, 30_000);

long startTime = System.nanoTime();
while(true){
runner.run();
if(counter.incrementAndGet() == Long.MAX_VALUE){
timer.cancel();
long endTime = System.nanoTime();
long elapsedTime = endTime - startTime;
System.out.printf("Finished: %d ns\n", elapsedTime);
}
}
}

public static void main(String[] args){
if(args.length < 1){
System.err.println("You should specify the mode.");
System.exit(1);
}
String mode = args[0];

var inst = new FuncCallComparison();
inst.setup();

if(mode.equals("single")){
inst.singleRun();
}
else if(mode.equals("iterate")){
if(args.length != 2){
System.err.println("You should specify the benchmark.");
System.exit(2);
}
inst.iterate(args[1]);
}
else{
System.err.println("Unknown mode.");
System.exit(3);
}
}

}

0 comments on commit fff651f

Please sign in to comment.