Extract chunk system threads to general common threads
This allows us to use them for chunk rendering, which should reduce competition between the background executor pool and the chunk system for cpu resources.
This commit is contained in:
@@ -13,8 +13,9 @@ public final class PlaceholderConfig {
|
||||
public static int autoSaveInterval = 60 * 5 * 20; // 5 mins
|
||||
public static int maxAutoSaveChunksPerTick = 12;
|
||||
|
||||
public static int workerThreads = -1;
|
||||
|
||||
public static int chunkSystemIOThreads = -1;
|
||||
public static int chunkSystemThreads = -1;
|
||||
public static String chunkSystemGenParallelism = "default";
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package ca.spottedleaf.moonrise.common.util;
|
||||
|
||||
import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedThreadPool;
|
||||
import ca.spottedleaf.moonrise.common.config.PlaceholderConfig;
|
||||
import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public final class MoonriseCommon {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ChunkTaskScheduler.class);
|
||||
|
||||
public static final PrioritisedThreadPool WORKER_POOL;
|
||||
public static final int WORKER_THREADS;
|
||||
static {
|
||||
int defaultWorkerThreads = Runtime.getRuntime().availableProcessors() / 2;
|
||||
if (defaultWorkerThreads <= 4) {
|
||||
defaultWorkerThreads = defaultWorkerThreads <= 3 ? 1 : 2;
|
||||
} else {
|
||||
defaultWorkerThreads = defaultWorkerThreads / 2;
|
||||
}
|
||||
defaultWorkerThreads = Integer.getInteger("Moonrise.WorkerThreadCount", Integer.valueOf(defaultWorkerThreads));
|
||||
|
||||
int workerThreads = PlaceholderConfig.workerThreads;
|
||||
|
||||
if (workerThreads < 0) {
|
||||
workerThreads = defaultWorkerThreads;
|
||||
} else {
|
||||
workerThreads = Math.max(1, workerThreads);
|
||||
}
|
||||
|
||||
WORKER_POOL = new PrioritisedThreadPool(
|
||||
"Moonrise Chunk System Worker Pool", workerThreads,
|
||||
(final Thread thread, final Integer id) -> {
|
||||
thread.setName("Moonrise Chunk System Worker #" + id.intValue());
|
||||
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
||||
@Override
|
||||
public void uncaughtException(final Thread thread, final Throwable throwable) {
|
||||
LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable);
|
||||
}
|
||||
});
|
||||
}, (long)(20.0e6)); // 20ms
|
||||
WORKER_THREADS = workerThreads;
|
||||
}
|
||||
|
||||
private MoonriseCommon() {}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package ca.spottedleaf.moonrise.mixin.chunk_system;
|
||||
|
||||
import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor;
|
||||
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
|
||||
import ca.spottedleaf.moonrise.common.util.MoonriseCommon;
|
||||
import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread;
|
||||
import ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.ChunkDataController;
|
||||
import ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.EntityDataController;
|
||||
@@ -117,7 +118,7 @@ public abstract class ServerLevelMixin extends Level implements ChunkSystemServe
|
||||
this.poiDataController = new PoiDataController((ServerLevel)(Object)this);
|
||||
this.chunkDataController = new ChunkDataController((ServerLevel)(Object)this);
|
||||
this.moonrise$setEntityLookup(new ServerEntityLookup((ServerLevel)(Object)this, ((ServerLevel)(Object)this).new EntityCallbacks()));
|
||||
this.chunkTaskScheduler = new ChunkTaskScheduler((ServerLevel)(Object)this, ChunkTaskScheduler.workerThreads);
|
||||
this.chunkTaskScheduler = new ChunkTaskScheduler((ServerLevel)(Object)this, MoonriseCommon.WORKER_POOL);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package ca.spottedleaf.moonrise.mixin.render;
|
||||
|
||||
import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor;
|
||||
import ca.spottedleaf.moonrise.common.util.MoonriseCommon;
|
||||
import net.minecraft.client.renderer.chunk.SectionRenderDispatcher;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(SectionRenderDispatcher.class)
|
||||
public abstract class SectionRenderDispatcherMixin {
|
||||
|
||||
@Unique
|
||||
private static final PrioritisedExecutor RENDER_EXECUTOR = MoonriseCommon.WORKER_POOL.createExecutor(
|
||||
"Moonrise Render Executor", 1, MoonriseCommon.WORKER_THREADS
|
||||
);
|
||||
|
||||
/**
|
||||
* @reason Change executor to use our thread pool
|
||||
* Note: even at normal priority, our worker pool will try to share resources equally rather than having it
|
||||
* be a free-for-all
|
||||
* @author Spottedleaf
|
||||
*/
|
||||
@Redirect(
|
||||
method = "runTask",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Ljava/util/concurrent/CompletableFuture;supplyAsync(Ljava/util/function/Supplier;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;"
|
||||
)
|
||||
)
|
||||
private <U> CompletableFuture<U> changeExecutor(final Supplier<U> supplier, final Executor executor) {
|
||||
return CompletableFuture.supplyAsync(
|
||||
supplier,
|
||||
(final Runnable task) -> {
|
||||
RENDER_EXECUTOR.queueRunnable(task, PrioritisedExecutor.Priority.NORMAL);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock;
|
||||
import ca.spottedleaf.concurrentutil.util.ConcurrentUtil;
|
||||
import ca.spottedleaf.moonrise.common.config.PlaceholderConfig;
|
||||
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
|
||||
import ca.spottedleaf.moonrise.common.util.MoonriseCommon;
|
||||
import ca.spottedleaf.moonrise.common.util.TickThread;
|
||||
import ca.spottedleaf.moonrise.common.util.WorldUtil;
|
||||
import ca.spottedleaf.moonrise.patches.chunk_system.io.RegionFileIOThread;
|
||||
@@ -49,12 +50,9 @@ public final class ChunkTaskScheduler {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ChunkTaskScheduler.class);
|
||||
|
||||
static int newChunkSystemIOThreads;
|
||||
static int newChunkSystemWorkerThreads;
|
||||
static int newChunkSystemGenParallelism;
|
||||
static int newChunkSystemLoadParallelism;
|
||||
|
||||
public static PrioritisedThreadPool workerThreads;
|
||||
|
||||
private static boolean initialised = false;
|
||||
|
||||
public static void init() {
|
||||
@@ -63,25 +61,11 @@ public final class ChunkTaskScheduler {
|
||||
}
|
||||
initialised = true;
|
||||
newChunkSystemIOThreads = PlaceholderConfig.chunkSystemIOThreads;
|
||||
newChunkSystemWorkerThreads = PlaceholderConfig.chunkSystemThreads;
|
||||
if (newChunkSystemIOThreads < 0) {
|
||||
newChunkSystemIOThreads = 1;
|
||||
} else {
|
||||
newChunkSystemIOThreads = Math.max(1, newChunkSystemIOThreads);
|
||||
}
|
||||
int defaultWorkerThreads = Runtime.getRuntime().availableProcessors() / 2;
|
||||
if (defaultWorkerThreads <= 4) {
|
||||
defaultWorkerThreads = defaultWorkerThreads <= 3 ? 1 : 2;
|
||||
} else {
|
||||
defaultWorkerThreads = defaultWorkerThreads / 2;
|
||||
}
|
||||
defaultWorkerThreads = Integer.getInteger("Moonrise.WorkerThreadCount", Integer.valueOf(defaultWorkerThreads));
|
||||
|
||||
if (newChunkSystemWorkerThreads < 0) {
|
||||
newChunkSystemWorkerThreads = defaultWorkerThreads;
|
||||
} else {
|
||||
newChunkSystemWorkerThreads = Math.max(1, newChunkSystemWorkerThreads);
|
||||
}
|
||||
|
||||
String newChunkSystemGenParallelism = PlaceholderConfig.chunkSystemGenParallelism;
|
||||
if (newChunkSystemGenParallelism.equalsIgnoreCase("default")) {
|
||||
@@ -98,24 +82,12 @@ public final class ChunkTaskScheduler {
|
||||
throw new IllegalStateException("Invalid option for gen-parallelism: must be one of [on, off, enabled, disabled, true, false, default]");
|
||||
}
|
||||
|
||||
ChunkTaskScheduler.newChunkSystemGenParallelism = useParallelGen ? newChunkSystemWorkerThreads : 1;
|
||||
ChunkTaskScheduler.newChunkSystemLoadParallelism = newChunkSystemWorkerThreads;
|
||||
ChunkTaskScheduler.newChunkSystemGenParallelism = useParallelGen ? MoonriseCommon.WORKER_THREADS : 1;
|
||||
ChunkTaskScheduler.newChunkSystemLoadParallelism = MoonriseCommon.WORKER_THREADS;
|
||||
|
||||
RegionFileIOThread.init(newChunkSystemIOThreads);
|
||||
workerThreads = new PrioritisedThreadPool(
|
||||
"Paper Chunk System Worker Pool", newChunkSystemWorkerThreads,
|
||||
(final Thread thread, final Integer id) -> {
|
||||
thread.setPriority(Thread.NORM_PRIORITY - 2);
|
||||
thread.setName("Moonrise Chunk System Worker #" + id.intValue());
|
||||
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
||||
@Override
|
||||
public void uncaughtException(final Thread thread, final Throwable throwable) {
|
||||
LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable);
|
||||
}
|
||||
});
|
||||
}, (long)(20.0e6)); // 20ms
|
||||
|
||||
LOGGER.info("Chunk system is using " + newChunkSystemIOThreads + " I/O threads, " + newChunkSystemWorkerThreads + " worker threads, and gen parallelism of " + ChunkTaskScheduler.newChunkSystemGenParallelism + " threads");
|
||||
LOGGER.info("Chunk system is using " + newChunkSystemIOThreads + " I/O threads, " + MoonriseCommon.WORKER_THREADS + " worker threads, and gen parallelism of " + ChunkTaskScheduler.newChunkSystemGenParallelism + " threads");
|
||||
}
|
||||
|
||||
public static final TicketType<Long> CHUNK_LOAD = TicketType.create("chunk_system:chunk_load", Long::compareTo);
|
||||
|
||||
@@ -97,6 +97,7 @@
|
||||
"chunk_system.OptionsMixin",
|
||||
"collisions.LiquidBlockRendererMixin",
|
||||
"collisions.ParticleMixin",
|
||||
"render.SectionRenderDispatcherMixin",
|
||||
"serverlist.ClientConnectionMixin",
|
||||
"serverlist.ServerSelectionListMixin",
|
||||
"starlight.multiplayer.ClientPacketListenerMixin"
|
||||
|
||||
Reference in New Issue
Block a user