trying TuneInlinerExploration=1 (#662)
This commit is contained in:
parent
d496adb049
commit
e81326b83d
@ -19,6 +19,6 @@ source "$HOME/.sdkman/bin/sdkman-init.sh"
|
|||||||
sdk use java 21.0.2-graal 1>&2
|
sdk use java 21.0.2-graal 1>&2
|
||||||
|
|
||||||
if [ ! -f target/CalculateAverage_artsiomkorzun_image ]; then
|
if [ ! -f target/CalculateAverage_artsiomkorzun_image ]; then
|
||||||
NATIVE_IMAGE_OPTS="--gc=epsilon -O3 -march=native -R:MaxHeapSize=64m -H:-GenLoopSafepoints --enable-preview --initialize-at-build-time=dev.morling.onebrc.CalculateAverage_artsiomkorzun"
|
NATIVE_IMAGE_OPTS="--gc=epsilon -O3 -march=native -H:TuneInlinerExploration=1 -R:MaxHeapSize=64m -H:-GenLoopSafepoints --enable-preview --initialize-at-build-time=dev.morling.onebrc.CalculateAverage_artsiomkorzun"
|
||||||
native-image $NATIVE_IMAGE_OPTS -cp target/average-1.0.0-SNAPSHOT.jar -o target/CalculateAverage_artsiomkorzun_image dev.morling.onebrc.CalculateAverage_artsiomkorzun
|
native-image $NATIVE_IMAGE_OPTS -cp target/average-1.0.0-SNAPSHOT.jar -o target/CalculateAverage_artsiomkorzun_image dev.morling.onebrc.CalculateAverage_artsiomkorzun
|
||||||
fi
|
fi
|
@ -26,6 +26,7 @@ import java.nio.file.StandardOpenOption;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
@ -81,8 +82,17 @@ public class CalculateAverage_artsiomkorzun {
|
|||||||
private static void spawn() throws Exception {
|
private static void spawn() throws Exception {
|
||||||
ProcessHandle.Info info = ProcessHandle.current().info();
|
ProcessHandle.Info info = ProcessHandle.current().info();
|
||||||
ArrayList<String> commands = new ArrayList<>();
|
ArrayList<String> commands = new ArrayList<>();
|
||||||
info.command().ifPresent(commands::add);
|
Optional<String> command = info.command();
|
||||||
info.arguments().ifPresent(args -> commands.addAll(Arrays.asList(args)));
|
Optional<String[]> arguments = info.arguments();
|
||||||
|
|
||||||
|
if (command.isPresent()) {
|
||||||
|
commands.add(command.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arguments.isPresent()) {
|
||||||
|
commands.addAll(Arrays.asList(arguments.get()));
|
||||||
|
}
|
||||||
|
|
||||||
commands.add("--worker");
|
commands.add("--worker");
|
||||||
|
|
||||||
new ProcessBuilder()
|
new ProcessBuilder()
|
||||||
@ -113,7 +123,7 @@ public class CalculateAverage_artsiomkorzun {
|
|||||||
aggregators[i].join();
|
aggregators[i].join();
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Aggregate> aggregates = result.get().aggregate();
|
Map<String, Aggregate> aggregates = result.get().build();
|
||||||
System.out.println(text(aggregates));
|
System.out.println(text(aggregates));
|
||||||
System.out.close();
|
System.out.close();
|
||||||
}
|
}
|
||||||
@ -163,14 +173,14 @@ public class CalculateAverage_artsiomkorzun {
|
|||||||
return Math.round(v) / 10.0;
|
return Math.round(v) / 10.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private record Aggregate(long min, long max, long sum, long cnt) {
|
private record Aggregate(int min, int max, long sum, int cnt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Aggregates {
|
private static class Aggregates {
|
||||||
|
|
||||||
private static final long ENTRIES = 64 * 1024;
|
private static final long ENTRIES = 64 * 1024;
|
||||||
private static final long SIZE = 256 * ENTRIES;
|
private static final long SIZE = 128 * ENTRIES;
|
||||||
private static final long MASK = (ENTRIES - 1) << 8;
|
private static final long MASK = (ENTRIES - 1) << 7;
|
||||||
|
|
||||||
private final long pointer;
|
private final long pointer;
|
||||||
|
|
||||||
@ -182,25 +192,25 @@ public class CalculateAverage_artsiomkorzun {
|
|||||||
|
|
||||||
public long find(long word, long hash) {
|
public long find(long word, long hash) {
|
||||||
long address = pointer + offset(hash);
|
long address = pointer + offset(hash);
|
||||||
long w = word(address + 48);
|
long w = word(address + 24);
|
||||||
return (w == word) ? address : 0;
|
return (w == word) ? address : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long find(long word1, long word2, long hash) {
|
public long find(long word1, long word2, long hash) {
|
||||||
long address = pointer + offset(hash);
|
long address = pointer + offset(hash);
|
||||||
long w1 = word(address + 48);
|
long w1 = word(address + 24);
|
||||||
long w2 = word(address + 56);
|
long w2 = word(address + 32);
|
||||||
return (word1 == w1) && (word2 == w2) ? address : 0;
|
return (word1 == w1) && (word2 == w2) ? address : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long put(long reference, long word, long length, long hash) {
|
public long put(long reference, long word, long length, long hash) {
|
||||||
for (long offset = offset(hash);; offset = next(offset)) {
|
for (long offset = offset(hash);; offset = next(offset)) {
|
||||||
long address = pointer + offset;
|
long address = pointer + offset;
|
||||||
if (equal(reference, word, address + 48, length)) {
|
if (equal(reference, word, address + 24, length)) {
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
long len = UNSAFE.getLong(address);
|
int len = UNSAFE.getInt(address);
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
alloc(reference, length, hash, address);
|
alloc(reference, length, hash, address);
|
||||||
return address;
|
return address;
|
||||||
@ -209,76 +219,76 @@ public class CalculateAverage_artsiomkorzun {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void update(long address, long value) {
|
public static void update(long address, long value) {
|
||||||
long sum = UNSAFE.getLong(address + 16) + value;
|
long sum = UNSAFE.getLong(address + 8) + value;
|
||||||
long cnt = UNSAFE.getLong(address + 24) + 1;
|
int cnt = UNSAFE.getInt(address + 16) + 1;
|
||||||
long min = UNSAFE.getLong(address + 32);
|
short min = UNSAFE.getShort(address + 20);
|
||||||
long max = UNSAFE.getLong(address + 40);
|
short max = UNSAFE.getShort(address + 22);
|
||||||
|
|
||||||
UNSAFE.putLong(address + 16, sum);
|
UNSAFE.putLong(address + 8, sum);
|
||||||
UNSAFE.putLong(address + 24, cnt);
|
UNSAFE.putInt(address + 16, cnt);
|
||||||
|
|
||||||
if (value < min) {
|
if (value < min) {
|
||||||
UNSAFE.putLong(address + 32, value);
|
UNSAFE.putShort(address + 20, (short) value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value > max) {
|
if (value > max) {
|
||||||
UNSAFE.putLong(address + 40, value);
|
UNSAFE.putShort(address + 22, (short) value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void merge(Aggregates rights) {
|
public void merge(Aggregates rights) {
|
||||||
for (int rightOffset = 0; rightOffset < SIZE; rightOffset += 256) {
|
for (long rightOffset = 0; rightOffset < SIZE; rightOffset += 128) {
|
||||||
long rightAddress = rights.pointer + rightOffset;
|
long rightAddress = rights.pointer + rightOffset;
|
||||||
long length = UNSAFE.getLong(rightAddress);
|
int length = UNSAFE.getInt(rightAddress);
|
||||||
|
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
long hash = UNSAFE.getLong(rightAddress + 8);
|
int hash = UNSAFE.getInt(rightAddress + 4);
|
||||||
|
|
||||||
for (long offset = offset(hash);; offset = next(offset)) {
|
for (long offset = offset(hash);; offset = next(offset)) {
|
||||||
long address = pointer + offset;
|
long address = pointer + offset;
|
||||||
|
|
||||||
if (equal(address + 48, rightAddress + 48, length)) {
|
if (equal(address + 24, rightAddress + 24, length)) {
|
||||||
long sum = UNSAFE.getLong(address + 16) + UNSAFE.getLong(rightAddress + 16);
|
long sum = UNSAFE.getLong(address + 8) + UNSAFE.getLong(rightAddress + 8);
|
||||||
long cnt = UNSAFE.getLong(address + 24) + UNSAFE.getLong(rightAddress + 24);
|
int cnt = UNSAFE.getInt(address + 16) + UNSAFE.getInt(rightAddress + 16);
|
||||||
long min = Math.min(UNSAFE.getLong(address + 32), UNSAFE.getLong(rightAddress + 32));
|
short min = (short) Math.min(UNSAFE.getShort(address + 20), UNSAFE.getShort(rightAddress + 20));
|
||||||
long max = Math.max(UNSAFE.getLong(address + 40), UNSAFE.getLong(rightAddress + 40));
|
short max = (short) Math.max(UNSAFE.getShort(address + 22), UNSAFE.getShort(rightAddress + 22));
|
||||||
|
|
||||||
UNSAFE.putLong(address + 16, sum);
|
UNSAFE.putLong(address + 8, sum);
|
||||||
UNSAFE.putLong(address + 24, cnt);
|
UNSAFE.putInt(address + 16, cnt);
|
||||||
UNSAFE.putLong(address + 32, min);
|
UNSAFE.putShort(address + 20, min);
|
||||||
UNSAFE.putLong(address + 40, max);
|
UNSAFE.putShort(address + 22, max);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
long len = UNSAFE.getLong(address);
|
int len = UNSAFE.getInt(address);
|
||||||
|
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
UNSAFE.copyMemory(rightAddress, address, length + 48);
|
UNSAFE.copyMemory(rightAddress, address, length + 24);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Aggregate> aggregate() {
|
public Map<String, Aggregate> build() {
|
||||||
TreeMap<String, Aggregate> set = new TreeMap<>();
|
TreeMap<String, Aggregate> set = new TreeMap<>();
|
||||||
|
|
||||||
for (long offset = 0; offset < SIZE; offset += 256) {
|
for (long offset = 0; offset < SIZE; offset += 128) {
|
||||||
long address = pointer + offset;
|
long address = pointer + offset;
|
||||||
long length = UNSAFE.getLong(address);
|
int length = UNSAFE.getInt(address);
|
||||||
|
|
||||||
if (length != 0) {
|
if (length != 0) {
|
||||||
byte[] array = new byte[(int) length - 1];
|
byte[] array = new byte[length - 1];
|
||||||
UNSAFE.copyMemory(null, address + 48, array, Unsafe.ARRAY_BYTE_BASE_OFFSET, array.length);
|
UNSAFE.copyMemory(null, address + 24, array, Unsafe.ARRAY_BYTE_BASE_OFFSET, array.length);
|
||||||
String key = new String(array);
|
String key = new String(array);
|
||||||
|
|
||||||
long sum = UNSAFE.getLong(address + 16);
|
long sum = UNSAFE.getLong(address + 8);
|
||||||
long cnt = UNSAFE.getLong(address + 24);
|
int cnt = UNSAFE.getInt(address + 16);
|
||||||
long min = UNSAFE.getLong(address + 32);
|
short min = UNSAFE.getShort(address + 20);
|
||||||
long max = UNSAFE.getLong(address + 40);
|
short max = UNSAFE.getShort(address + 22);
|
||||||
|
|
||||||
Aggregate aggregate = new Aggregate(min, max, sum, cnt);
|
Aggregate aggregate = new Aggregate(min, max, sum, cnt);
|
||||||
set.put(key, aggregate);
|
set.put(key, aggregate);
|
||||||
@ -289,11 +299,11 @@ public class CalculateAverage_artsiomkorzun {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void alloc(long reference, long length, long hash, long address) {
|
private static void alloc(long reference, long length, long hash, long address) {
|
||||||
UNSAFE.putLong(address, length);
|
UNSAFE.putInt(address, (int) length);
|
||||||
UNSAFE.putLong(address + 8, hash);
|
UNSAFE.putInt(address + 4, (int) hash);
|
||||||
UNSAFE.putLong(address + 32, Long.MAX_VALUE);
|
UNSAFE.putShort(address + 20, Short.MAX_VALUE);
|
||||||
UNSAFE.putLong(address + 40, Long.MIN_VALUE);
|
UNSAFE.putShort(address + 22, Short.MIN_VALUE);
|
||||||
UNSAFE.copyMemory(reference, address + 48, length);
|
UNSAFE.copyMemory(reference, address + 24, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long offset(long hash) {
|
private static long offset(long hash) {
|
||||||
@ -301,7 +311,7 @@ public class CalculateAverage_artsiomkorzun {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static long next(long prev) {
|
private static long next(long prev) {
|
||||||
return (prev + 256) & (SIZE - 1);
|
return (prev + 128) & (SIZE - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean equal(long leftAddress, long leftWord, long rightAddress, long length) {
|
private static boolean equal(long leftAddress, long leftWord, long rightAddress, long length) {
|
||||||
@ -510,8 +520,9 @@ public class CalculateAverage_artsiomkorzun {
|
|||||||
private static long value(Chunk chunk) {
|
private static long value(Chunk chunk) {
|
||||||
long num = word(chunk.position);
|
long num = word(chunk.position);
|
||||||
long dot = dot(num);
|
long dot = dot(num);
|
||||||
|
long value = value(num, dot);
|
||||||
chunk.position += (dot >> 3) + 3;
|
chunk.position += (dot >> 3) + 3;
|
||||||
return value(num, dot);
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long separator(long word) {
|
private static long separator(long word) {
|
||||||
|
Loading…
Reference in New Issue
Block a user