From 393ea10cdfee323c14a447d07c0fad91090117c4 Mon Sep 17 00:00:00 2001 From: Brian Neumann-Fopiano Date: Wed, 21 Oct 2026 21:58:31 -0400 Subject: [PATCH 1/2] Pregen hydrology reach - Pregen tile speculation limited to the generation reach around the area instead of a 512-block halo --- .../hydrology/HydrologyTileCache.java | 2 +- .../hydrology/HydrologyTileCacheTest.java | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/art/arcane/iris/generation/hydrology/HydrologyTileCache.java b/core/src/main/java/art/arcane/iris/generation/hydrology/HydrologyTileCache.java index bc8178418..b4ff8db4f 100644 --- a/core/src/main/java/art/arcane/iris/generation/hydrology/HydrologyTileCache.java +++ b/core/src/main/java/art/arcane/iris/generation/hydrology/HydrologyTileCache.java @@ -43,7 +43,7 @@ public final class HydrologyTileCache implements AutoCloseable { private static final byte AROUND_EMPTY = 1; private static final byte AROUND_PUBLISHED = 2; private static final int MAXIMUM_PREGENERATION_TILES = 4096; - private static final int PREGENERATION_HALO_BLOCKS = 512; + private static final int PREGENERATION_HALO_BLOCKS = 256; private static final HydrologyColumnSample[] NO_COLUMNS = new HydrologyColumnSample[CHUNK_COLUMN_COUNT]; private static final Cache SHARED_TILES = Caffeine.newBuilder() .maximumWeight(HydrologyCacheBudget.sharedStudioBytes()) diff --git a/core/src/test/java/art/arcane/iris/generation/hydrology/HydrologyTileCacheTest.java b/core/src/test/java/art/arcane/iris/generation/hydrology/HydrologyTileCacheTest.java index f9b670632..817a6c7e7 100644 --- a/core/src/test/java/art/arcane/iris/generation/hydrology/HydrologyTileCacheTest.java +++ b/core/src/test/java/art/arcane/iris/generation/hydrology/HydrologyTileCacheTest.java @@ -696,6 +696,29 @@ public class HydrologyTileCacheTest { cache.close(); } + @Test + public void pregenSpeculationStaysWithinTheGenerationReachOfTheArea() { + HydrologyPlanner planner = mock(HydrologyPlanner.class); + HydrologyTile tile = mock(HydrologyTile.class); + HydrologyPlannerSettings settings = stalePrefetchSettings(); + when(planner.settings()).thenReturn(settings); + ArrayList planned = new ArrayList<>(); + doAnswer(invocation -> { + planned.add(invocation.getArgument(0)); + return tile; + }).when(planner).plan(any(HydrologyTileKey.class)); + HydrologyTileCache cache = new HydrologyTileCache(planner, 128, Runnable::run); + try (HydrologyTileCache.PregenerationScope ignored = cache.preparePregeneration( + new HydrologyTileCache.PregenerationArea(1024, 1024, 736, 736, 1311, 1311))) { + assertEquals(prefetchRectangle(0, 1, 0, 1), new HashSet<>(planned)); + cache.prepareChunkColumns(800, 800); + cache.prepareChunkColumns(1300, 1300); + assertEquals(prefetchRectangle(0, 1, 0, 1), new HashSet<>(planned)); + assertEquals(4, planned.size()); + } + cache.close(); + } + @Test public void pregenScopesRestoreStudioPrefetchAndIgnoreSupersededClose() { HydrologyPlanner planner = mock(HydrologyPlanner.class); From 35e4e30ecdad9c37eae086e73e9fc443344172b4 Mon Sep 17 00:00:00 2001 From: Brian Neumann-Fopiano Date: Wed, 21 Oct 2026 21:58:31 -0400 Subject: [PATCH 2/2] Performance core pools - Generation pool sized to performance cores - Pregen burst raise sized from performance cores - Hydrology planner pool sized to performance cores, at least four --- .../iris/generation/concurrent/MultiBurst.java | 13 ++++++++++--- .../iris/world/pregen/PregenPerformanceProfile.java | 7 ++++--- .../generation/concurrent/HydrologyBurstTest.java | 8 ++++++++ .../world/pregen/PregenPerformanceProfileTest.java | 2 +- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/art/arcane/iris/generation/concurrent/MultiBurst.java b/core/src/main/java/art/arcane/iris/generation/concurrent/MultiBurst.java index 0969ba03d..66fe2961c 100644 --- a/core/src/main/java/art/arcane/iris/generation/concurrent/MultiBurst.java +++ b/core/src/main/java/art/arcane/iris/generation/concurrent/MultiBurst.java @@ -26,7 +26,7 @@ public class MultiBurst extends MultiBurstSupport { private final AtomicInteger parallelismBaseline = new AtomicInteger(); public MultiBurst() { - this("Iris"); + this("Iris", Thread.MIN_PRIORITY, MultiBurstSupport::performanceProcessors); } public MultiBurst(String name) { @@ -140,8 +140,15 @@ public class MultiBurst extends MultiBurstSupport { static final class HydrologyBurst extends MultiBurst { HydrologyBurst() { - super("Iris Hydrology", () -> Math.max(2, - IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getParallelism()))); + super("Iris Hydrology", HydrologyBurst::plannerParallelism); + } + + static int plannerParallelism() { + return plannerParallelism(MultiBurstSupport.performanceProcessors()); + } + + static int plannerParallelism(int performanceProcessors) { + return Math.max(4, performanceProcessors); } @Override diff --git a/core/src/main/java/art/arcane/iris/world/pregen/PregenPerformanceProfile.java b/core/src/main/java/art/arcane/iris/world/pregen/PregenPerformanceProfile.java index c5d5b10b2..3fc3c3b2c 100644 --- a/core/src/main/java/art/arcane/iris/world/pregen/PregenPerformanceProfile.java +++ b/core/src/main/java/art/arcane/iris/world/pregen/PregenPerformanceProfile.java @@ -24,6 +24,7 @@ import art.arcane.iris.generation.runtime.Engine; import art.arcane.iris.platform.generation.PlatformChunkGenerator; import art.arcane.iris.spi.IrisLogging; import art.arcane.iris.generation.concurrent.MultiBurst; +import art.arcane.volmlib.util.parallel.MultiBurstSupport; import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; @@ -45,7 +46,7 @@ public final class PregenPerformanceProfile { changed = true; } - if (MultiBurst.burst.raiseParallelism(pregenBurstParallelism(Runtime.getRuntime().availableProcessors()))) { + if (MultiBurst.burst.raiseParallelism(pregenBurstParallelism(MultiBurstSupport.performanceProcessors()))) { PARALLELISM_HOLDERS.incrementAndGet(); changed = true; } @@ -88,8 +89,8 @@ public final class PregenPerformanceProfile { apply(generator == null ? null : generator.getEngine()); } - static int pregenBurstParallelism(int availableProcessors) { - return Math.max(4, availableProcessors * 2); + static int pregenBurstParallelism(int performanceProcessors) { + return Math.max(4, performanceProcessors * 2); } private static void prepareNoiseCacheInPlace(Engine engine) { diff --git a/core/src/test/java/art/arcane/iris/generation/concurrent/HydrologyBurstTest.java b/core/src/test/java/art/arcane/iris/generation/concurrent/HydrologyBurstTest.java index 7aa6ababd..bd0aca932 100644 --- a/core/src/test/java/art/arcane/iris/generation/concurrent/HydrologyBurstTest.java +++ b/core/src/test/java/art/arcane/iris/generation/concurrent/HydrologyBurstTest.java @@ -12,6 +12,7 @@ import java.util.concurrent.ForkJoinTask; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; @@ -60,6 +61,13 @@ public class HydrologyBurstTest { assertTrue(pool.isTerminated()); } + @Test + public void plannerPoolFollowsThePerformanceCores() { + assertEquals(12, MultiBurst.HydrologyBurst.plannerParallelism(12)); + assertEquals(4, MultiBurst.HydrologyBurst.plannerParallelism(1)); + assertEquals(32, MultiBurst.HydrologyBurst.plannerParallelism(32)); + } + @Test public void closedHydrologyWorkersTerminateAndReopenCreatesANewPool() throws Exception { IrisSettings previousSettings = IrisSettings.settings; diff --git a/core/src/test/java/art/arcane/iris/world/pregen/PregenPerformanceProfileTest.java b/core/src/test/java/art/arcane/iris/world/pregen/PregenPerformanceProfileTest.java index 96c0e407f..21f574cc0 100644 --- a/core/src/test/java/art/arcane/iris/world/pregen/PregenPerformanceProfileTest.java +++ b/core/src/test/java/art/arcane/iris/world/pregen/PregenPerformanceProfileTest.java @@ -99,7 +99,7 @@ public class PregenPerformanceProfileTest { } @Test - public void pregenerationWantsTwoBurstWorkersPerCore() { + public void pregenerationWantsTwoBurstWorkersPerPerformanceCore() { assertEquals(32, PregenPerformanceProfile.pregenBurstParallelism(16)); assertEquals(4, PregenPerformanceProfile.pregenBurstParallelism(1)); }