aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAikar <[email protected]>2020-07-30 22:01:32 -0400
committerAikar <[email protected]>2020-07-30 22:04:56 -0400
commit3cf2c52d9559d450acd19af42e5ba539f16b3851 (patch)
treef73bcbbc79b3a53a7ad5019ed82fd335ca10992d
parent0b33230f2db4013d929b4b2e93b74ea57592a6d6 (diff)
downloadPaper-3cf2c52d9559d450acd19af42e5ba539f16b3851.tar.gz
Paper-3cf2c52d9559d450acd19af42e5ba539f16b3851.zip
Improve Light Optimizations more
Hopefully fixes #4030 and hopefully fixes #4025 Use the concurrent enqueue process for all light tasks. Restore dedicated light thread, helpful for profiling and identifying light work as well as lets us give it a boosted thread priority
-rw-r--r--Spigot-Server-Patches/0505-Optimize-Light-Engine.patch97
1 files changed, 60 insertions, 37 deletions
diff --git a/Spigot-Server-Patches/0505-Optimize-Light-Engine.patch b/Spigot-Server-Patches/0505-Optimize-Light-Engine.patch
index f7bbb509b1..68495f116d 100644
--- a/Spigot-Server-Patches/0505-Optimize-Light-Engine.patch
+++ b/Spigot-Server-Patches/0505-Optimize-Light-Engine.patch
@@ -1027,10 +1027,10 @@ index a35e7b392c74fadf2760d1fc2021e98d33858cb5..944094e8e770cc8c0205ef2aa6c48fff
lightenginelayer.a(Long.MAX_VALUE, l3, 15, false);
}
diff --git a/src/main/java/net/minecraft/server/LightEngineThreaded.java b/src/main/java/net/minecraft/server/LightEngineThreaded.java
-index a9dc8466278f9ec2becbcb643e6e1c973df72b82..1e70754529847e077f88af01c087aba6a887c039 100644
+index a9dc8466278f9ec2becbcb643e6e1c973df72b82..9d6d882ad1479771b2a9e7c3a14c71dd00b63172 100644
--- a/src/main/java/net/minecraft/server/LightEngineThreaded.java
+++ b/src/main/java/net/minecraft/server/LightEngineThreaded.java
-@@ -15,15 +15,153 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
+@@ -15,15 +15,158 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
private static final Logger LOGGER = LogManager.getLogger();
private final ThreadedMailbox<Runnable> b;
@@ -1056,17 +1056,19 @@ index a9dc8466278f9ec2becbcb643e6e1c973df72b82..1e70754529847e077f88af01c087aba6
+ ChunkLightQueue(long chunk) {}
+ }
+
-+ static class PendingChunkLight {
++ static class PendingLightTask {
+ long chunkId;
-+ int priority;
++ IntSupplier priority;
+ Runnable pre;
+ Runnable post;
++ boolean fastUpdate;
+
-+ public PendingChunkLight(long chunkId, int priority, Runnable pre, Runnable post) {
++ public PendingLightTask(long chunkId, IntSupplier priority, Runnable pre, Runnable post, boolean fastUpdate) {
+ this.chunkId = chunkId;
+ this.priority = priority;
+ this.pre = pre;
+ this.post = post;
++ this.fastUpdate = fastUpdate;
+ }
+ }
+
@@ -1076,7 +1078,7 @@ index a9dc8466278f9ec2becbcb643e6e1c973df72b82..1e70754529847e077f88af01c087aba6
+ private int size = 0;
+ private int lowestPriority = MAX_PRIORITIES;
+ private final it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap<ChunkLightQueue>[] buckets = new it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap[MAX_PRIORITIES];
-+ private final java.util.concurrent.ConcurrentLinkedQueue<PendingChunkLight> pendingChunks = new java.util.concurrent.ConcurrentLinkedQueue<>();
++ private final java.util.concurrent.ConcurrentLinkedQueue<PendingLightTask> pendingTasks = new java.util.concurrent.ConcurrentLinkedQueue<>();
+ private final java.util.concurrent.ConcurrentLinkedQueue<Runnable> priorityChanges = new java.util.concurrent.ConcurrentLinkedQueue<>();
+
+ private LightQueue() {
@@ -1095,7 +1097,7 @@ index a9dc8466278f9ec2becbcb643e6e1c973df72b82..1e70754529847e077f88af01c087aba6
+ remove.post.addAll(existing.post);
+ }
+ }
-+ if (this.buckets[priority].containsKey(pair)) {
++ if (!this.buckets[priority].isEmpty()) {
+ if (lowestPriority > priority) {
+ lowestPriority = priority;
+ }
@@ -1103,23 +1105,27 @@ index a9dc8466278f9ec2becbcb643e6e1c973df72b82..1e70754529847e077f88af01c087aba6
+ });
+ }
+
-+ public final void addChunk(long chunkId, int priority, Runnable pre, Runnable post) {
-+ pendingChunks.add(new PendingChunkLight(chunkId, priority, pre, post));
++ public final void addChunk(long chunkId, IntSupplier priority, Runnable pre, Runnable post) {
++ pendingTasks.add(new PendingLightTask(chunkId, priority, pre, post, true));
+ queueUpdate();
+ }
+
-+ public final void add(long chunkId, int priority, LightEngineThreaded.Update type, Runnable run) {
-+ add(chunkId, priority, type, run, false);
++ public final void add(long chunkId, IntSupplier priority, LightEngineThreaded.Update type, Runnable run) {
++ pendingTasks.add(new PendingLightTask(chunkId, priority, type == Update.PRE_UPDATE ? run : null, type == Update.POST_UPDATE ? run : null, false));
+ }
-+ public final void add(long chunkId, int priority, LightEngineThreaded.Update type, Runnable run, boolean shouldFastUpdate) {
-+ ChunkLightQueue lightQueue = this.buckets[priority].computeIfAbsent(chunkId, ChunkLightQueue::new);
-+ this.size++;
-+ if (type == Update.PRE_UPDATE) {
-+ lightQueue.pre.add(run);
-+ } else {
-+ lightQueue.post.add(run);
++ public final void add(PendingLightTask update) {
++ int priority = update.priority.getAsInt();
++ ChunkLightQueue lightQueue = this.buckets[priority].computeIfAbsent(update.chunkId, ChunkLightQueue::new);
++
++ if (update.pre != null) {
++ this.size++;
++ lightQueue.pre.add(update.pre);
++ }
++ if (update.post != null) {
++ this.size++;
++ lightQueue.post.add(update.post);
+ }
-+ if (shouldFastUpdate) {
++ if (update.fastUpdate) {
+ lightQueue.shouldFastUpdate = true;
+ }
+
@@ -1129,7 +1135,7 @@ index a9dc8466278f9ec2becbcb643e6e1c973df72b82..1e70754529847e077f88af01c087aba6
+ }
+
+ public final boolean isEmpty() {
-+ return this.size == 0 && this.pendingChunks.isEmpty();
++ return this.size == 0 && this.pendingTasks.isEmpty();
+ }
+
+ public final int size() {
@@ -1137,10 +1143,9 @@ index a9dc8466278f9ec2becbcb643e6e1c973df72b82..1e70754529847e077f88af01c087aba6
+ }
+
+ public boolean poll(java.util.List<Runnable> pre, java.util.List<Runnable> post) {
-+ PendingChunkLight chunk;
-+ while ((chunk = pendingChunks.poll()) != null) {
-+ add(chunk.chunkId, chunk.priority, Update.PRE_UPDATE, chunk.pre, true);
-+ add(chunk.chunkId, chunk.priority, Update.POST_UPDATE, chunk.post, true);
++ PendingLightTask pending;
++ while ((pending = pendingTasks.poll()) != null) {
++ add(pending);
+ }
+ Runnable run;
+ while ((run = priorityChanges.poll()) != null) {
@@ -1187,22 +1192,24 @@ index a9dc8466278f9ec2becbcb643e6e1c973df72b82..1e70754529847e077f88af01c087aba6
this.e = mailbox;
this.b = threadedmailbox;
}
-@@ -111,10 +249,10 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
+@@ -110,13 +253,9 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
+ }
private void a(int i, int j, IntSupplier intsupplier, LightEngineThreaded.Update lightenginethreaded_update, Runnable runnable) {
- this.e.a(ChunkTaskQueueSorter.a(() -> {
+- this.e.a(ChunkTaskQueueSorter.a(() -> {
- this.c.add(Pair.of(lightenginethreaded_update, runnable));
- if (this.c.size() >= this.f) {
- this.b();
- }
-+ // Paper start
-+ int priority = intsupplier.getAsInt();
-+ this.queue.add(ChunkCoordIntPair.pair(i, j), priority, lightenginethreaded_update, runnable);
-+ // Paper end
-
- }, ChunkCoordIntPair.pair(i, j), intsupplier));
+-
+- }, ChunkCoordIntPair.pair(i, j), intsupplier));
++ // Paper start - replace method
++ this.queue.add(ChunkCoordIntPair.pair(i, j), intsupplier, lightenginethreaded_update, runnable);
++ // Paper end
}
-@@ -133,8 +271,21 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
+
+ @Override
+@@ -133,8 +272,20 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
public CompletableFuture<IChunkAccess> a(IChunkAccess ichunkaccess, boolean flag) {
ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos();
@@ -1214,8 +1221,7 @@ index a9dc8466278f9ec2becbcb643e6e1c973df72b82..1e70754529847e077f88af01c087aba6
+ CompletableFuture<IChunkAccess> future = new CompletableFuture<>();
+ IntSupplier prioritySupplier = playerChunkMap.getPrioritySupplier(pair);
+ boolean[] skippedPre = {false};
-+ int priority = prioritySupplier.getAsInt();
-+ this.queue.addChunk(pair, priority, SystemUtils.a(() -> {
++ this.queue.addChunk(pair, prioritySupplier, SystemUtils.a(() -> {
+ if (!isChunkLightStatus(pair)) {
+ this.d.c(chunkcoordintpair); // copied from end of method to release light ticket
+ future.complete(ichunkaccess);
@@ -1336,10 +1342,27 @@ index 446c401b3139f8c6c0e70d883340f0140d94b752..c14cdb60243e16810ad711d204678d51
if (getCurrentPriority() != priority) {
this.v.a(this.location, this::getCurrentPriority, priority, this::setPriority); // use preferred priority
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
-index fea219dcfd5a98fc0e48fd70dc7d0fd41b2fc970..ad8a00e0fb5da5df1eb3afbf9ea50acfc89a5ff1 100644
+index fea219dcfd5a98fc0e48fd70dc7d0fd41b2fc970..0c70689f525ccfd069f14ea8ef156aa2fa8a854e 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
-@@ -653,6 +653,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+@@ -306,7 +306,15 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
+ Mailbox<Runnable> mailbox = Mailbox.a("main", iasynctaskhandler::a);
+
+ this.worldLoadListener = worldloadlistener;
+- ThreadedMailbox<Runnable> lightthreaded; ThreadedMailbox<Runnable> threadedmailbox1 = lightthreaded = ThreadedMailbox.a(executor, "light"); // Paper
++ // Paper start - use light thread
++ ThreadedMailbox<Runnable> lightthreaded; ThreadedMailbox<Runnable> threadedmailbox1 = lightthreaded = ThreadedMailbox.a(java.util.concurrent.Executors.newSingleThreadExecutor(r -> {
++ Thread thread = new Thread(r);
++ thread.setName(((WorldDataServer)world.getWorldData()).getName() + " - Light");
++ thread.setDaemon(true);
++ thread.setPriority(Thread.NORM_PRIORITY+1);
++ return thread;
++ }), "light");
++ // Paper end
+
+ this.p = new ChunkTaskQueueSorter(ImmutableList.of(threadedmailbox, mailbox, threadedmailbox1), executor, Integer.MAX_VALUE);
+ this.mailboxWorldGen = this.p.a(threadedmailbox, false);
+@@ -653,6 +661,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
// Paper end
}