diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 43a36f2248..f4843499a8 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -23,7 +23,7 @@ repositories { dependencies { //TODO Allow pulling from Versions.kt implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.6") - + implementation("me.champeau.jmh", "me.champeau.jmh.gradle.plugin", "0.7.3") implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "2.0.0-beta.17") implementation("org.ow2.asm", "asm", "9.8") implementation("org.ow2.asm", "asm-tree", "9.8") diff --git a/buildSrc/src/main/kotlin/BenchmarkingConfig.kt b/buildSrc/src/main/kotlin/BenchmarkingConfig.kt new file mode 100644 index 0000000000..696b463d44 --- /dev/null +++ b/buildSrc/src/main/kotlin/BenchmarkingConfig.kt @@ -0,0 +1,6 @@ +import org.gradle.api.Project +import org.gradle.kotlin.dsl.apply + +fun Project.configureBenchmarking() { + apply(plugin = "me.champeau.jmh") +} \ No newline at end of file diff --git a/common/addons/chunk-generator-noise-3d/build.gradle.kts b/common/addons/chunk-generator-noise-3d/build.gradle.kts index 3640ad0547..e0c34bc3b0 100644 --- a/common/addons/chunk-generator-noise-3d/build.gradle.kts +++ b/common/addons/chunk-generator-noise-3d/build.gradle.kts @@ -3,3 +3,5 @@ version = version("1.2.1") dependencies { compileOnlyApi(project(":common:addons:manifest-addon-loader")) } + +configureBenchmarking() diff --git a/common/addons/chunk-generator-noise-3d/src/jmh/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/Interpolator3Benchmark.java b/common/addons/chunk-generator-noise-3d/src/jmh/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/Interpolator3Benchmark.java new file mode 100644 index 0000000000..4417ba7b02 --- /dev/null +++ b/common/addons/chunk-generator-noise-3d/src/jmh/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/Interpolator3Benchmark.java @@ -0,0 +1,22 @@ +package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +@State(Scope.Benchmark) +@Fork(1) +@Warmup(iterations = 2, time = 1) +@Measurement(iterations = 2, time = 5) +public class Interpolator3Benchmark { + private final Interpolator3 interpolator = new Interpolator3(0, 1, 0, 1, 0, 1, 0, 1); + + @Benchmark + public void benchmarkInterpolator3(Blackhole blackhole) { + blackhole.consume(interpolator.trilerp(0.5, 0.75, 0.5)); + } +} diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/Interpolator.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/Interpolator.java deleted file mode 100644 index 62fc2d836f..0000000000 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/Interpolator.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2020-2025 Polyhedral Development - * - * The Terra Core Addons are licensed under the terms of the MIT License. For more details, - * reference the LICENSE file in this module's root directory. - */ - -package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation; - - -import com.dfsek.seismic.math.numericanalysis.interpolation.InterpolationFunctions; - - -/** - * Class for bilinear interpolation of values arranged on a unit square. - */ -public class Interpolator { - private final double v0, v1, v2, v3; - - /** - * Constructs an interpolator with given values as vertices of a unit square. - * - * @param v0 - (0,0) - * @param v1 - (1,0) - * @param v2 - (0,1) - * @param v3 - (1,1) - */ - public Interpolator(double v0, double v1, double v2, double v3) { - this.v0 = v0; - this.v1 = v1; - this.v2 = v2; - this.v3 = v3; - } - - //TODO this system is not very good, replace it wholesale - - /** - * 2D Bilinear interpolation between 4 points on a unit square. - * - * @param s - X value - * @param t - Z value - * - * @return double - The interpolated value. - */ - public double bilerp(double s, double t) { - double v01 = InterpolationFunctions.lerp(v0, v1, s); - double v23 = InterpolationFunctions.lerp(v2, v3, s); - return InterpolationFunctions.lerp(v01, v23, t); - } -} \ No newline at end of file diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/Interpolator3.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/Interpolator3.java index 5c07e767e9..7445e6be5c 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/Interpolator3.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/Interpolator3.java @@ -7,16 +7,21 @@ package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation; - -import com.dfsek.seismic.math.numericanalysis.interpolation.InterpolationFunctions; +import com.dfsek.seismic.math.arithmetic.ArithmeticFunctions; /** * Class for bilinear interpolation of values arranged on a unit square. */ public class Interpolator3 { - private final Interpolator bottom; - private final Interpolator top; + private final double _000; + private final double _001; + private final double _010; + private final double _011; + private final double _100; + private final double _101; + private final double _110; + private final double _111; /** * Constructs an interpolator with given values as vertices of a unit cube. @@ -33,12 +38,25 @@ public Interpolator3(double _000, double _100, double _010, double _110, double _001, double _101, double _011, double _111) { - this.top = new Interpolator(_000, _010, _001, _011); - this.bottom = new Interpolator(_100, _110, _101, _111); + this._000 = _000; + this._001 = _001; + this._010 = _010; + this._011 = _011; + this._100 = _100; + this._101 = _101; + this._110 = _110; + this._111 = _111; } - //TODO this system is not very good, replace it wholesale public double trilerp(double x, double y, double z) { - return InterpolationFunctions.lerp(top.bilerp(y, z), bottom.bilerp(y, z), x); + double a = ArithmeticFunctions.fma(2, x, -1); + double b = ArithmeticFunctions.fma(2, y, -1); + double g = ArithmeticFunctions.fma(2, z, -1); + + // using explicit fma here somehow makes this slower + return ((1 - g) * (1 - b) * (1 - a) * _000 + (1 - g) * (1 - b) * (1 + a) * _100 + + (1 - g) * (1 + b) * (1 - a) * _010 + (1 - g) * (1 + b) * (1 + a) * _110 + + (1 + g) * (1 - b) * (1 - a) * _001 + (1 + g) * (1 - b) * (1 + a) * _101 + + (1 + g) * (1 + b) * (1 - a) * _011 + (1 + g) * (1 + b) * (1 + a) * _111) / 8; } } \ No newline at end of file diff --git a/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java b/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java index 69bcb16807..7bf5b22164 100644 --- a/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java +++ b/platforms/minestom/example/src/main/java/com/dfsek/terra/minestom/TerraMinestomExample.java @@ -59,7 +59,7 @@ private void sendProgressBar(int current, int max) { } public void preloadWorldAndMeasure() { - int radius = 12; + int radius = 32; int chunksLoading = (radius * 2 + 1) * (radius * 2 + 1); AtomicInteger chunksLeft = new AtomicInteger(chunksLoading); diff --git a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/GeneratedChunkCache.java b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/GeneratedChunkCache.java index a84477fef5..b4571d15a0 100644 --- a/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/GeneratedChunkCache.java +++ b/platforms/minestom/src/main/java/com/dfsek/terra/minestom/chunk/GeneratedChunkCache.java @@ -15,7 +15,7 @@ public class GeneratedChunkCache { private static final Logger log = LoggerFactory.getLogger(GeneratedChunkCache.class); - private final LoadingCache, CachedChunk> cache; + private final LoadingCache cache; private final DimensionType dimensionType; private final ChunkGenerator generator; private final ServerWorld world; @@ -29,7 +29,7 @@ public GeneratedChunkCache(DimensionType dimensionType, ChunkGenerator generator this.cache = Caffeine.newBuilder() .maximumSize(128) .recordStats() - .build((Pair key) -> generateChunk(key.getLeft(), key.getRight())); + .build((Long key) -> generateChunk(unpackX(key), unpackZ(key))); } private CachedChunk generateChunk(int x, int z) { @@ -50,6 +50,18 @@ public void displayStats() { } public CachedChunk at(int x, int z) { - return cache.get(Pair.of(x, z)); + return cache.get(pack(x, z)); + } + + private long pack(final int x, final int z) { + return ((long) x & 0xFFFFFFFFL) << 32 | (z & 0xFFFFFFFFL); + } + + private int unpackX(long packed) { + return (int) (packed >> 32); + } + + private int unpackZ(long packed) { + return (int) packed; } }