mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-26 15:06:28 +01:00
Unionized threads
- Allow the user to configure the number of worker threads - Allow the user to disable parallelism entirely without a jvm flag - Move thread count logic into FlwTaskExecutor and make ParallelTaskExecutor simply take a thread count as a parameter
This commit is contained in:
parent
d5c5b998bc
commit
506f2d5158
7 changed files with 41 additions and 22 deletions
|
@ -66,5 +66,5 @@ public interface TaskExecutor extends Executor {
|
|||
*
|
||||
* @return The number of threads this executor uses.
|
||||
*/
|
||||
int getThreadCount();
|
||||
int threadCount();
|
||||
}
|
||||
|
|
|
@ -66,6 +66,10 @@ public class FlwConfig {
|
|||
return client.limitUpdates.get();
|
||||
}
|
||||
|
||||
public int workerThreads() {
|
||||
return client.workerThreads.get();
|
||||
}
|
||||
|
||||
public void registerSpecs(ModLoadingContext context) {
|
||||
context.registerConfig(ModConfig.Type.CLIENT, clientSpec);
|
||||
}
|
||||
|
@ -73,6 +77,7 @@ public class FlwConfig {
|
|||
public static class ClientConfig {
|
||||
public final ConfigValue<String> backend;
|
||||
public final BooleanValue limitUpdates;
|
||||
public final ForgeConfigSpec.IntValue workerThreads;
|
||||
|
||||
private ClientConfig(ForgeConfigSpec.Builder builder) {
|
||||
backend = builder.comment("Select the backend to use.")
|
||||
|
@ -80,6 +85,10 @@ public class FlwConfig {
|
|||
|
||||
limitUpdates = builder.comment("Enable or disable instance update limiting with distance.")
|
||||
.define("limitUpdates", true);
|
||||
|
||||
workerThreads = builder.comment("The number of worker threads to use. Set to -1 to let Flywheel decide. Set to 0 to disable parallelism. Requires a game restart to take effect.")
|
||||
.defineInRange("workerThreads", -1, -1, Runtime.getRuntime()
|
||||
.availableProcessors());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,11 +4,12 @@ import org.apache.commons.lang3.concurrent.AtomicSafeInitializer;
|
|||
import org.apache.commons.lang3.concurrent.ConcurrentUtils;
|
||||
|
||||
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
public final class FlwTaskExecutor {
|
||||
public static final boolean USE_SERIAL_EXECUTOR = System.getProperty("flw.useSerialExecutor") != null;
|
||||
import net.minecraft.util.Mth;
|
||||
|
||||
public final class FlwTaskExecutor {
|
||||
private static final Initializer INITIALIZER = new Initializer();
|
||||
|
||||
private FlwTaskExecutor() {
|
||||
|
@ -22,14 +23,34 @@ public final class FlwTaskExecutor {
|
|||
return ConcurrentUtils.initializeUnchecked(INITIALIZER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the "optimal" number of threads to be used for tasks. This will always return at least one thread.
|
||||
*/
|
||||
private static int getOptimalThreadCount() {
|
||||
return Mth.clamp(Math.max(getMaxThreadCount() / 3, getMaxThreadCount() - 6), 1, 10);
|
||||
}
|
||||
|
||||
private static int getMaxThreadCount() {
|
||||
return Runtime.getRuntime()
|
||||
.availableProcessors();
|
||||
}
|
||||
|
||||
|
||||
private static class Initializer extends AtomicSafeInitializer<TaskExecutor> {
|
||||
@Override
|
||||
protected TaskExecutor initialize() {
|
||||
if (USE_SERIAL_EXECUTOR) {
|
||||
int threadCount = FlwConfig.get()
|
||||
.workerThreads();
|
||||
|
||||
if (threadCount == 0) {
|
||||
return SerialTaskExecutor.INSTANCE;
|
||||
} else if (threadCount < 0) {
|
||||
threadCount = getOptimalThreadCount();
|
||||
} else {
|
||||
threadCount = Mth.clamp(threadCount, 1, getMaxThreadCount());
|
||||
}
|
||||
|
||||
ParallelTaskExecutor executor = new ParallelTaskExecutor("Flywheel", RenderSystem::isOnRenderThread);
|
||||
ParallelTaskExecutor executor = new ParallelTaskExecutor("Flywheel", threadCount, RenderSystem::isOnRenderThread);
|
||||
executor.startWorkers();
|
||||
return executor;
|
||||
}
|
||||
|
|
|
@ -38,14 +38,14 @@ public class ParallelTaskExecutor implements TaskExecutor {
|
|||
private final ThreadGroupNotifier taskNotifier = new ThreadGroupNotifier();
|
||||
private final WaitGroup waitGroup = new WaitGroup();
|
||||
|
||||
public ParallelTaskExecutor(String name, BooleanSupplier mainThreadQuery) {
|
||||
public ParallelTaskExecutor(String name, int threadCount, BooleanSupplier mainThreadQuery) {
|
||||
this.name = name;
|
||||
this.mainThreadQuery = mainThreadQuery;
|
||||
threadCount = getOptimalThreadCount();
|
||||
this.threadCount = threadCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getThreadCount() {
|
||||
public int threadCount() {
|
||||
return threadCount;
|
||||
}
|
||||
|
||||
|
@ -247,17 +247,6 @@ public class ParallelTaskExecutor implements TaskExecutor {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the "optimal" number of threads to be used for tasks. This will always return at least one thread.
|
||||
*/
|
||||
private static int getOptimalThreadCount() {
|
||||
return Mth.clamp(Math.max(getMaxThreadCount() / 3, getMaxThreadCount() - 6), 1, 10);
|
||||
}
|
||||
|
||||
private static int getMaxThreadCount() {
|
||||
return Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
private class WorkerThread extends Thread {
|
||||
public WorkerThread(String name) {
|
||||
super(name);
|
||||
|
|
|
@ -35,7 +35,7 @@ public class SerialTaskExecutor implements TaskExecutor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int getThreadCount() {
|
||||
public int threadCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ public final class Distribute {
|
|||
}
|
||||
|
||||
public static int sliceSize(TaskExecutor taskExecutor, int totalSize, int denominator) {
|
||||
return MoreMath.ceilingDiv(totalSize, taskExecutor.getThreadCount() * denominator);
|
||||
return MoreMath.ceilingDiv(totalSize, taskExecutor.threadCount() * denominator);
|
||||
}
|
||||
|
||||
private Distribute() {
|
||||
|
|
|
@ -27,7 +27,7 @@ class PlanExecutionTest {
|
|||
@BeforeEach
|
||||
public void setUp() {
|
||||
var currentThread = Thread.currentThread();
|
||||
EXECUTOR = new ParallelTaskExecutor("PlanTest", () -> currentThread == Thread.currentThread());
|
||||
EXECUTOR = new ParallelTaskExecutor("PlanTest", 2, () -> currentThread == Thread.currentThread());
|
||||
EXECUTOR.startWorkers();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue