From 8a0b443d2833875fbf3f838abb19faf1ce138bd3 Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Thu, 26 Oct 2023 17:28:43 +0200 Subject: [PATCH] Pack Benchmarking - Iris pregen is broken what it relies on so it doesnt work. Issue: Generated and total chunks dont end up as the same value after the pregen is done --- core/src/main/java/com/volmit/iris/Iris.java | 4 + .../iris/core/commands/CommandIris.java | 23 ++- .../iris/core/commands/CommandPregen.java | 3 +- .../core/pregenerator/IrisPregenerator.java | 34 +++- .../iris/core/tools/IrisBenchmarking.java | 3 +- .../volmit/iris/core/tools/IrisCreator.java | 33 ++-- .../iris/core/tools/IrisPackBenchmarking.java | 151 +++++++++++++++++- .../volmit/iris/engine/IrisEngineMantle.java | 21 ++- 8 files changed, 247 insertions(+), 25 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/Iris.java b/core/src/main/java/com/volmit/iris/Iris.java index dad3af14c..ea60c21e2 100644 --- a/core/src/main/java/com/volmit/iris/Iris.java +++ b/core/src/main/java/com/volmit/iris/Iris.java @@ -95,6 +95,8 @@ import java.util.Map; import static com.volmit.iris.engine.safeguard.IrisSafeguard.unstablemode; import static com.volmit.iris.engine.safeguard.ServerBootSFG.passedserversoftware; +import static com.volmit.iris.util.misc.getHardware.getCPUModel; +import static com.volmit.iris.util.misc.getHardware.getCPUThreads; @SuppressWarnings("CanBeFinal") public class Iris extends VolmitPlugin implements Listener { @@ -771,6 +773,8 @@ public class Iris extends VolmitPlugin implements Listener { } else { Iris.info("Server type & version: " + Bukkit.getVersion()); } Iris.info("Server OS: " + osName + " (" + osArch + ")"); + Iris.info("Server Cpu: " + C.BLUE + getCPUModel()); + Iris.info("Process Threads: " + getCPUThreads()); Iris.info("Process Memory: " + maxMemory + " MB"); if (maxMemory < 5999) { Iris.warn("6GB+ Ram is recommended"); diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index c5e4358be..708a01fda 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -22,6 +22,7 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.service.StudioSVC; import com.volmit.iris.core.tools.IrisBenchmarking; +import com.volmit.iris.core.tools.IrisPackBenchmarking; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.IrisDimension; @@ -41,6 +42,8 @@ import com.volmit.iris.util.parallel.MultiBurst; import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.jobs.QueueJob; +import lombok.Getter; +import lombok.Setter; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.World; @@ -52,6 +55,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import static com.volmit.iris.core.tools.IrisBenchmarking.inProgress; +import static com.volmit.iris.core.tools.IrisPackBenchmarking.runBenchmark; import static com.volmit.iris.engine.safeguard.ServerBootSFG.multiverse; @Decree(name = "iris", aliases = {"ir", "irs"}, description = "Basic Command") @@ -66,6 +70,8 @@ public class CommandIris implements DecreeExecutor { private CommandFind find; private CommandWorldManager manager; + public static @Getter String BenchDimension; + @Decree(description = "Create a new world", aliases = {"+", "c"}) public void create( @Param(aliases = "world-name", description = "The name of the world to create") @@ -88,6 +94,11 @@ public class CommandIris implements DecreeExecutor { sender().sendMessage(C.RED + "May we suggest the name \"IrisWorld\" instead?"); return; } + if (name.equals("Benchmark")) { + sender().sendMessage(C.RED + "You cannot use the world name \"Benchmark\" for creating worlds as Iris uses this directory for Benchmarking Packs."); + sender().sendMessage(C.RED + "May we suggest the name \"IrisWorld\" instead?"); + return; + } if (new File(Bukkit.getWorldContainer(), name).exists()) { sender().sendMessage(C.RED + "That folder already exists!"); @@ -142,13 +153,23 @@ public class CommandIris implements DecreeExecutor { sender().sendMessage(C.GREEN + "Iris v" + Iris.instance.getDescription().getVersion() + " by Volmit Software"); } @Decree(description = "Benchmark your server", origin = DecreeOrigin.CONSOLE) - public void benchmark() throws InterruptedException { + public void serverbenchmark() throws InterruptedException { if(!inProgress) { IrisBenchmarking.runBenchmark(); } else { Iris.info(C.RED + "Benchmark already is in progress."); } } + @Decree(description = "Benchmark a pack", origin = DecreeOrigin.CONSOLE) + public void packbenchmark( + @Param(description = "Dimension to benchmark") + IrisDimension type + ) throws InterruptedException { + + BenchDimension = type.getLoadKey(); + + IrisPackBenchmarking.runBenchmark(); + } @Decree(description = "Print world height information", origin = DecreeOrigin.PLAYER) public void height() { diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandPregen.java b/core/src/main/java/com/volmit/iris/core/commands/CommandPregen.java index 32906de2a..c92f373ce 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandPregen.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandPregen.java @@ -67,7 +67,8 @@ public class CommandPregen implements DecreeExecutor { @Decree(description = "Stop the active pregeneration task", aliases = "x") public void stop() { if (PregeneratorJob.shutdownInstance()) { - sender().sendMessage(C.GREEN + "Stopped pregeneration task"); + Iris.info( C.BLUE + "Finishing up mca region..."); + sender().sendMessage(C.DARK_BLUE + "Stopped pregeneration task"); } else { sender().sendMessage(C.YELLOW + "No active pregeneration tasks to stop"); } diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java index 9ef0faebf..a66ec20d6 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java @@ -19,7 +19,9 @@ package com.volmit.iris.core.pregenerator; import com.volmit.iris.Iris; +import com.volmit.iris.core.tools.IrisPackBenchmarking; import com.volmit.iris.util.collection.KSet; +import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.math.M; @@ -28,12 +30,16 @@ import com.volmit.iris.util.math.RollingSequence; import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.Looper; +import lombok.Getter; +import lombok.Setter; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; +import static com.volmit.iris.core.tools.IrisPackBenchmarking.benchmark; + public class IrisPregenerator { private final PregenTask task; private final PregeneratorMethod generator; @@ -44,10 +50,10 @@ public class IrisPregenerator { private final RollingSequence chunksPerSecond; private final RollingSequence chunksPerMinute; private final RollingSequence regionsPerMinute; - private final AtomicInteger generated; + private static AtomicInteger generated; private final AtomicInteger generatedLast; private final AtomicInteger generatedLastMinute; - private final AtomicInteger totalChunks; + private static AtomicInteger totalChunks; private final AtomicLong startTime; private final ChronoLatch minuteLatch; private final AtomicReference currentGeneratorMethod; @@ -56,6 +62,8 @@ public class IrisPregenerator { private final KSet net; private final ChronoLatch cl; private final ChronoLatch saveLatch = new ChronoLatch(30000); + static long long_generatedChunks = 0; + static long long_totalChunks = 0; public IrisPregenerator(PregenTask task, PregeneratorMethod generator, PregenListener listener) { this.listener = listenify(listener); @@ -92,6 +100,8 @@ public class IrisPregenerator { chunksPerMinute.put(minuteGenerated); regionsPerMinute.put((double) minuteGenerated / 1024D); } + long_generatedChunks = generated.get(); + long_totalChunks = totalChunks.get(); listener.onTick(chunksPerSecond.getAverage(), chunksPerMinute.getAverage(), regionsPerMinute.getAverage(), @@ -102,9 +112,12 @@ public class IrisPregenerator { if (cl.flip()) { double percentage = ((double) generated.get() / (double) totalChunks.get()) * 100; - Iris.info("Pregen: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration((double) eta, 2), percentage); + if(benchmark) { + Iris.info(C.GREEN +"Benchmark: " + C.WHITE + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration((double) eta, 2), percentage); + } else { + Iris.info("Pregen: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration((double) eta, 2), percentage); + } } - return 1000; } }; @@ -119,6 +132,19 @@ public class IrisPregenerator { ); } + public static void shareData(){ + long_generatedChunks = generated.get(); + long_totalChunks = totalChunks.get(); + } + + public static long getLongGeneratedChunks() { + return long_generatedChunks; + } + public static long getLongTotalChunks() { + return long_totalChunks; + } + + public void close() { shutdown.set(true); } diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisBenchmarking.java b/core/src/main/java/com/volmit/iris/core/tools/IrisBenchmarking.java index 39d27ffcd..300a4467f 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisBenchmarking.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisBenchmarking.java @@ -29,11 +29,9 @@ import java.io.InputStreamReader; import static com.google.common.math.LongMath.isPrime; import static com.volmit.iris.util.misc.getHardware.getCPUModel; import static com.volmit.iris.util.misc.getHardware.getDiskModel; - public class IrisBenchmarking { static String ServerOS; static String filePath = "benchmark.dat"; - private static long startTime; static double avgWriteSpeedMBps; static double avgReadSpeedMBps; static double highestWriteSpeedMBps; @@ -58,6 +56,7 @@ public class IrisBenchmarking { static boolean Winsat = false; static boolean WindowsDiskSpeed = false; public static boolean inProgress = false; + static double startTime; // Good enough for now. . . public static void runBenchmark() throws InterruptedException { diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java b/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java index 372a63a74..f9af5dd7f 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java @@ -45,6 +45,9 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Supplier; +import static com.volmit.iris.core.tools.IrisPackBenchmarking.benchmark; +import static com.volmit.iris.core.tools.IrisPackBenchmarking.loaded; + /** * Makes it a lot easier to setup an engine, world, studio or whatever */ @@ -93,6 +96,9 @@ public class IrisCreator { yml.save(BUKKIT_YML); return true; } + public static boolean worldLoaded(){ + return true; + } /** * Create the IrisAccess (contains the world) @@ -100,6 +106,7 @@ public class IrisCreator { * @return the IrisAccess * @throws IrisException shit happens */ + IrisPackBenchmarking PackBench = new IrisPackBenchmarking(); public World create() throws IrisException { if (Bukkit.isPrimaryThread()) { throw new IrisException("You cannot invoke create() on the main thread."); @@ -117,6 +124,9 @@ public class IrisCreator { if (!studio()) { Iris.service(StudioSVC.class).installIntoWorld(sender, d.getLoadKey(), new File(Bukkit.getWorldContainer(), name())); } + if (benchmark) { + Iris.service(StudioSVC.class).installIntoWorld(sender, d.getLoadKey(), new File(Bukkit.getWorldContainer(), name())); + } PlatformChunkGenerator access = null; AtomicReference world = new AtomicReference<>(); @@ -143,17 +153,20 @@ public class IrisCreator { } return finalAccess1.getEngine().getGenerated(); }; - while (g.get() < req) { - double v = (double) g.get() / (double) req; - - if (sender.isPlayer()) { - sender.sendProgress(v, "Generating"); - J.sleep(16); - } else { - sender.sendMessage(C.WHITE + "Generating " + Form.pc(v) + ((C.GRAY + " (" + (req - g.get()) + " Left)"))); - J.sleep(1000); + if(!benchmark) { + while (g.get() < req) { + double v = (double) g.get() / (double) req; + if (sender.isPlayer()) { + sender.sendProgress(v, "Generating"); + J.sleep(16); + } else { + sender.sendMessage(C.WHITE + "Generating " + Form.pc(v) + ((C.GRAY + " (" + (req - g.get()) + " Left)"))); + J.sleep(1000); + } } } + //if (benchmark){loaded = true;} + Iris.info("Debug1"); }); @@ -177,7 +190,7 @@ public class IrisCreator { }); } - if (studio) { + if (studio || benchmark) { J.s(() -> { Iris.linkMultiverseCore.removeFromConfig(world.get()); diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java b/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java index 65b4bfe31..099005b87 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java @@ -1,9 +1,156 @@ package com.volmit.iris.core.tools; +import com.volmit.iris.Iris; +import com.volmit.iris.core.pregenerator.IrisPregenerator; +import com.volmit.iris.core.pregenerator.PregenTask; +import com.volmit.iris.util.exceptions.IrisException; +import com.volmit.iris.util.format.C; +import com.volmit.iris.util.math.Position2; + +import com.volmit.iris.util.scheduling.J; +import org.apache.commons.io.FileUtils; +import org.bukkit.Bukkit; + +import java.io.File; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import static com.volmit.iris.core.commands.CommandIris.BenchDimension; + + public class IrisPackBenchmarking { - public static void runBenchmark(){ - + public static boolean loaded = false; + public static boolean benchmark = false; + static boolean cancelled = false; + static boolean pregenInProgress = false; + static long startTime; + static long totalChunks; + static long generatedChunks; + static double elapsedTimeNs; + + public static void runBenchmark() { + // IrisPackBenchmarking IrisPackBenchmarking = new IrisPackBenchmarking(); + benchmark = true; + Iris.info(C.BLUE + "Benchmarking Dimension: " + C.AQUA + BenchDimension); + + //progress(); + CompletableFuture future = CompletableFuture.runAsync(() -> { + Iris.info(C.GOLD + "Setting everything up.."); + try { + String BenchmarkFolder = "\\Benchmark"; + File folder = new File(BenchmarkFolder); + if (folder.exists() && folder.isDirectory()) { + FileUtils.deleteDirectory(folder); + Iris.debug("Deleted old Benchmark"); + } else { + Iris.info(C.GOLD + "Old Benchmark not found!"); + if(folder.exists()){ + Iris.info(C.RED + "FAILED To remove old Benchmark!"); + //cancelled = true; + } + } + } catch (Exception e) { + throw new RuntimeException(); + } + + }).thenRun(() -> { + Iris.info(C.GOLD + "Creating Benchmark Environment"); + createBenchmark(); + + }).thenRun(() -> { + Iris.info( C.BLUE + "Benchmark Started!"); + boolean done = false; + startBenchmarkTimer(); + startBenchmark(); + basicScheduler(); + }).thenRun(() -> { + + }); + // cancelled = future.cancel(true); + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } } + private static void results(){ + double averageCps = calculateAverageCPS(); + Iris.info("Benchmark Dimension: " + BenchDimension); + Iris.info("Speeds"); + Iris.info("- Average CPS: " + roundToTwoDecimalPlaces(averageCps)); + Iris.info("Duration: " + roundToTwoDecimalPlaces(elapsedTimeNs)); + + } + private static void basicScheduler() { + while (true) { + totalChunks = IrisPregenerator.getLongTotalChunks(); + generatedChunks = IrisPregenerator.getLongGeneratedChunks(); + Iris.info("TEST: "+ totalChunks); + Iris.info("TEST2: "+ generatedChunks); + if(totalChunks > 0) { + if (generatedChunks >= totalChunks) { + Iris.info("Benchmark Completed!"); + elapsedTimeNs = stopBenchmarkTimer(); + results(); + break; + } + } + //J.sleep(100); + } + } + static void createBenchmark(){ + try { + IrisToolbelt.createWorld() + .dimension(BenchDimension) + .name("Benchmark") + .seed(1337) + .studio(false) + .create(); + } catch (IrisException e) { + throw new RuntimeException(e); + } + } + static void startBenchmark(){ + int x = 0; + int z = 0; + IrisToolbelt.pregenerate(PregenTask + .builder() + .center(new Position2(x, z)) + .width(5) + .height(5) + .build(), Bukkit.getWorld("Benchmark") + ); + } + public static double calculateAverageCPS() { + double elapsedTimeSec = elapsedTimeNs / 1_000_000_000.0; // Convert to seconds + return generatedChunks / elapsedTimeSec; + } + + private static void startBenchmarkTimer() { + startTime = System.nanoTime(); + } + + private static double stopBenchmarkTimer() { + long endTime = System.nanoTime(); + return (endTime - startTime) / 1_000_000_000.0; + } + + public static void deleteDirectory(File dir) { + File[] files = dir.listFiles(); + if(files != null) { + for(File file: files) { + if(file.isDirectory()) { + deleteDirectory(file); + } else { + file.delete(); + } + } + } + dir.delete(); + } + private static double roundToTwoDecimalPlaces(double value) { + return Double.parseDouble(String.format("%.2f", value)); + } } \ No newline at end of file diff --git a/core/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java b/core/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java index f2dd124a6..591f76c31 100644 --- a/core/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java +++ b/core/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java @@ -19,6 +19,8 @@ package com.volmit.iris.engine; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.core.tools.IrisPackBenchmarking; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.mantle.EngineMantle; @@ -31,6 +33,7 @@ import com.volmit.iris.engine.object.*; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KSet; +import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.parallel.BurstExecutor; @@ -42,6 +45,8 @@ import java.io.IOException; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +import static com.volmit.iris.core.tools.IrisPackBenchmarking.benchmark; + @Data public class IrisEngineMantle implements EngineMantle { private final Engine engine; @@ -280,11 +285,17 @@ public class IrisEngineMantle implements EngineMantle { x = Math.max(x, c); x = (Math.max(x, 16) + 16) >> 4; x = x % 2 == 0 ? x + 1 : x; - x = 4; - Iris.info("Mantle Size: " + x + " Chunks"); - Iris.info(" Object Mantle Size: " + u + " (" + ((Math.max(u, 16) + 16) >> 4) + ")"); - Iris.info(" Jigsaw Mantle Size: " + jig + " (" + ((Math.max(jig, 16) + 16) >> 4) + ")"); - Iris.info(" Carving Mantle Size: " + c + " (" + ((Math.max(c, 16) + 16) >> 4) + ")"); + IrisPackBenchmarking PackBench = new IrisPackBenchmarking(); + if (benchmark){ + x = 4; + Iris.info("Mantle Size: " + x + " Chunks " + C.BLUE + "BENCHMARK MODE"); + } else { + Iris.info("Mantle Size: " + x + " Chunks"); + Iris.info(" Object Mantle Size: " + u + " (" + ((Math.max(u, 16) + 16) >> 4) + ")"); + Iris.info(" Jigsaw Mantle Size: " + jig + " (" + ((Math.max(jig, 16) + 16) >> 4) + ")"); + Iris.info(" Carving Mantle Size: " + c + " (" + ((Math.max(c, 16) + 16) >> 4) + ")"); + } + return x; }