mirror of
https://github.com/PaperMC/Paper.git
synced 2025-02-08 07:03:47 +01:00
Optimize Light Engine
Massive update to light to improve performance and chunk loading/generation. 1) Massive bit packing/unpacking optimizations and inlining. A lot of performance has to do with constant packing and unpacking of bits. We now inline a most bit operations, and re-use base x/y/z bits in many places. This helps with cpu level processing to just do all the math at once instead of having to jump in and out of function calls. This much logic also is likely over the JVM Inline limit for JIT too. 2) Applied a few of JellySquid's Phosphor mod optimizations such as - ensuring we don't notify neighbor chunks when neighbor chunk doesn't need to be notified - reduce hasLight checks in initializing light, and prob some more, they are tagged JellySquid where phosphor influence was used. 3) Optimize hot path accesses to getting updating chunk to have less branching 4) Optimize getBlock accesses to have less branching, and less unpacking 5) Have a separate urgent bucket for chunk light tasks. These tasks will always cut in line over non blocking light tasks. 6) Retain chunk priority while light tasks are enqueued. So if a task comes in at high priority but the queue is full of tasks already at a lower priority, before the task was simply added to the end. Now it can cut in line to the front. this applies for both urgent and non urgent tasks. 7) Buffer non urgent tasks even if queueUpdate is called multiple times to improve efficiency. 8) Fix NPE risk that crashes server in getting nibble data Fixes #3489 Fixes #3363
This commit is contained in:
parent
9258a3ebcb
commit
799bd8f5e9
9 changed files with 1605 additions and 94 deletions
Spigot-Server-Patches
Anti-Xray.patchImplement-Chunk-Priority-Urgency-System-for-Chunks.patchOptimise-random-block-ticking.patchOptimize-Bit-Operations-by-inlining.patchOptimize-Light-Engine.patchOptimize-NibbleArray-to-use-pooled-buffers.patchOptimize-isValidLocation-getType-and-getBlockData-fo.patchReduce-MutableInt-allocations-from-light-engine.patchStop-copy-on-write-operations-for-updating-light-dat.patch
|
@ -1079,7 +1079,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ this.blockIds = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, Block.REGISTRY_ID, GameProfileSerializer::d, GameProfileSerializer::a, Blocks.AIR.getBlockData(), world == null ? null : world.chunkPacketBlockController.getPredefinedBlockData(world, chunk, this, initializeBlocks), initializeBlocks); // Paper - Anti-Xray - Add predefined block data
|
||||
}
|
||||
|
||||
public IBlockData getType(int i, int j, int k) {
|
||||
public final IBlockData getType(int i, int j, int k) { // Paper
|
||||
@@ -0,0 +0,0 @@ public class ChunkSection {
|
||||
return this.blockIds;
|
||||
}
|
||||
|
|
|
@ -392,32 +392,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
for (int i = 0; i < this.inventory.getSize(); ++i) {
|
||||
ItemStack itemstack = this.inventory.getItem(i);
|
||||
diff --git a/src/main/java/net/minecraft/server/LightEngineThreaded.java b/src/main/java/net/minecraft/server/LightEngineThreaded.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/LightEngineThreaded.java
|
||||
+++ b/src/main/java/net/minecraft/server/LightEngineThreaded.java
|
||||
@@ -0,0 +0,0 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
|
||||
ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos();
|
||||
|
||||
ichunkaccess.b(false);
|
||||
- this.a(chunkcoordintpair.x, chunkcoordintpair.z, LightEngineThreaded.Update.PRE_UPDATE, SystemUtils.a(() -> {
|
||||
+ // Paper start
|
||||
+ IntSupplier defSupplier = this.d.c(chunkcoordintpair.pair());
|
||||
+ IntSupplier priority = () -> Math.max(defSupplier.getAsInt() - 1, 1);
|
||||
+ // Paper end
|
||||
+ this.a(chunkcoordintpair.x, chunkcoordintpair.z, priority, LightEngineThreaded.Update.PRE_UPDATE, SystemUtils.a(() -> { // Paper - boost light priority
|
||||
ChunkSection[] achunksection = ichunkaccess.getSections();
|
||||
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
@@ -0,0 +0,0 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
|
||||
super.b(chunkcoordintpair, false);
|
||||
return ichunkaccess;
|
||||
}, (runnable) -> {
|
||||
- this.a(chunkcoordintpair.x, chunkcoordintpair.z, LightEngineThreaded.Update.POST_UPDATE, runnable);
|
||||
+ this.a(chunkcoordintpair.x, chunkcoordintpair.z, priority, LightEngineThreaded.Update.POST_UPDATE, runnable); // Paper - boost light priority
|
||||
});
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MCUtil.java
|
||||
|
|
|
@ -135,7 +135,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public static final DataPalette<IBlockData> GLOBAL_PALETTE = new DataPaletteGlobal<>(Block.REGISTRY_ID, Blocks.AIR.getBlockData());
|
||||
- private final int yPos;
|
||||
+ final int yPos; // Paper - private -> package-private
|
||||
private short nonEmptyBlockCount;
|
||||
short nonEmptyBlockCount; // Paper - package-private
|
||||
- private short tickingBlockCount;
|
||||
+ short tickingBlockCount; // Paper - private -> package-private
|
||||
private short e;
|
||||
|
|
234
Spigot-Server-Patches/Optimize-Bit-Operations-by-inlining.patch
Normal file
234
Spigot-Server-Patches/Optimize-Bit-Operations-by-inlining.patch
Normal file
|
@ -0,0 +1,234 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 4 Jun 2020 02:24:49 -0400
|
||||
Subject: [PATCH] Optimize Bit Operations by inlining
|
||||
|
||||
Inline bit operations and reduce instruction count to make these hot
|
||||
operations faster
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/BlockPosition.java
|
||||
+++ b/src/main/java/net/minecraft/server/BlockPosition.java
|
||||
@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali
|
||||
return dynamicops.createIntList(IntStream.of(new int[]{this.getX(), this.getY(), this.getZ()}));
|
||||
}
|
||||
|
||||
+ public static long getAdjacent(int baseX, int baseY, int baseZ, EnumDirection enumdirection) { return asLong(baseX + enumdirection.getAdjacentX(), baseY + enumdirection.getAdjacentY(), baseZ + enumdirection.getAdjacentZ()); } // Paper
|
||||
public static long a(long i, EnumDirection enumdirection) {
|
||||
return a(i, enumdirection.getAdjacentX(), enumdirection.getAdjacentY(), enumdirection.getAdjacentZ());
|
||||
}
|
||||
|
||||
public static long a(long i, int j, int k, int l) {
|
||||
- return a(b(i) + j, c(i) + k, d(i) + l);
|
||||
+ return a((int) (i >> 38) + j, (int) ((i << 52) >> 52) + k, (int) ((i << 26) >> 38) + l); // Paper - simplify/inline
|
||||
}
|
||||
|
||||
public static int b(long i) {
|
||||
- return (int) (i << 64 - BlockPosition.k - BlockPosition.c >> 64 - BlockPosition.c);
|
||||
+ return (int) (i >> 38); // Paper - simplify/inline
|
||||
}
|
||||
|
||||
public static int c(long i) {
|
||||
- return (int) (i << 64 - BlockPosition.f >> 64 - BlockPosition.f);
|
||||
+ return (int) ((i << 52) >> 52); // Paper - simplify/inline
|
||||
}
|
||||
|
||||
public static int d(long i) {
|
||||
- return (int) (i << 64 - BlockPosition.j - BlockPosition.d >> 64 - BlockPosition.d);
|
||||
+ return (int) ((i << 26) >> 38); // Paper - simplify/inline
|
||||
}
|
||||
|
||||
public static BlockPosition fromLong(long i) {
|
||||
- return new BlockPosition(b(i), c(i), d(i));
|
||||
+ return new BlockPosition((int) (i >> 38), (int) ((i << 52) >> 52), (int) ((i << 26) >> 38)); // Paper - simplify/inline
|
||||
}
|
||||
|
||||
public static long asLong(int x, int y, int z) { return a(x, y, z); } // Paper - OBFHELPER
|
||||
public static long a(int i, int j, int k) {
|
||||
- long l = 0L;
|
||||
-
|
||||
- l |= ((long) i & BlockPosition.g) << BlockPosition.k;
|
||||
- l |= ((long) j & BlockPosition.h) << 0;
|
||||
- l |= ((long) k & BlockPosition.i) << BlockPosition.j;
|
||||
- return l;
|
||||
+ return (((long) i & (long) 67108863) << 38) | (((long) j & (long) 4095)) | (((long) k & (long) 67108863) << 12); // Paper - inline constants and simplify
|
||||
}
|
||||
|
||||
public static long f(long i) {
|
||||
diff --git a/src/main/java/net/minecraft/server/SectionPosition.java b/src/main/java/net/minecraft/server/SectionPosition.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/SectionPosition.java
|
||||
+++ b/src/main/java/net/minecraft/server/SectionPosition.java
|
||||
@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
}
|
||||
|
||||
public static SectionPosition a(BlockPosition blockposition) {
|
||||
- return new SectionPosition(a(blockposition.getX()), a(blockposition.getY()), a(blockposition.getZ()));
|
||||
+ return new SectionPosition(blockposition.getX() >> 4, blockposition.getY() >> 4, blockposition.getZ() >> 4); // Paper
|
||||
}
|
||||
|
||||
public static SectionPosition a(ChunkCoordIntPair chunkcoordintpair, int i) {
|
||||
@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
}
|
||||
|
||||
public static SectionPosition a(long i) {
|
||||
- return new SectionPosition(b(i), c(i), d(i));
|
||||
+ return new SectionPosition((int) (i >> 42), (int) (i << 44 >> 44), (int) (i << 22 >> 42)); // Paper
|
||||
}
|
||||
|
||||
public static long a(long i, EnumDirection enumdirection) {
|
||||
@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
}
|
||||
|
||||
public static long a(long i, int j, int k, int l) {
|
||||
- return b(b(i) + j, c(i) + k, d(i) + l);
|
||||
+ return (((long) ((int) (i >> 42) + j) & 4194303L) << 42) | (((long) ((int) (i << 44 >> 44) + k) & 1048575L)) | (((long) ((int) (i << 22 >> 42) + l) & 4194303L) << 20); // Simplify to reduce instruction count
|
||||
}
|
||||
|
||||
public static int a(int i) {
|
||||
@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
}
|
||||
|
||||
public static short b(BlockPosition blockposition) {
|
||||
- int i = b(blockposition.getX());
|
||||
- int j = b(blockposition.getY());
|
||||
- int k = b(blockposition.getZ());
|
||||
-
|
||||
- return (short) (i << 8 | k << 4 | j);
|
||||
+ return (short) ((blockposition.x & 15) << 8 | (blockposition.z & 15) << 4 | blockposition.y & 15); // Paper - simplify/inline
|
||||
}
|
||||
|
||||
public static int c(int i) {
|
||||
@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
}
|
||||
|
||||
public static int b(long i) {
|
||||
- return (int) (i << 0 >> 42);
|
||||
+ return (int) (i >> 42); // Paper
|
||||
}
|
||||
|
||||
public static int c(long i) {
|
||||
@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
return (int) (i << 22 >> 42);
|
||||
}
|
||||
|
||||
- public int a() {
|
||||
- return this.getX();
|
||||
+ public final int a() { // Paper
|
||||
+ return x; // Paper
|
||||
}
|
||||
|
||||
- public int b() {
|
||||
- return this.getY();
|
||||
+ public final int b() { // Paper
|
||||
+ return y; // Paper
|
||||
}
|
||||
|
||||
- public int c() {
|
||||
- return this.getZ();
|
||||
+ public final int c() { // Paper
|
||||
+ return z; // Paper
|
||||
}
|
||||
|
||||
- public int d() {
|
||||
- return this.a() << 4;
|
||||
+ public final int d() { // Paper
|
||||
+ return x << 4; // Paper
|
||||
}
|
||||
|
||||
- public int e() {
|
||||
- return this.b() << 4;
|
||||
+ public final int e() { // Paper
|
||||
+ return y << 4; // Paper
|
||||
}
|
||||
|
||||
- public int f() {
|
||||
- return this.c() << 4;
|
||||
+ public final int f() { // Paper
|
||||
+ return z << 4; // Paper
|
||||
}
|
||||
|
||||
- public int g() {
|
||||
- return (this.a() << 4) + 15;
|
||||
+ public final int g() { // Paper
|
||||
+ return (x << 4) + 15; // Paper
|
||||
}
|
||||
|
||||
- public int h() {
|
||||
- return (this.b() << 4) + 15;
|
||||
+ public final int h() { // Paper
|
||||
+ return (y << 4) + 15; // Paper
|
||||
}
|
||||
|
||||
- public int r() {
|
||||
- return (this.c() << 4) + 15;
|
||||
+ public final int r() { // Paper
|
||||
+ return (z << 4) + 15; // Paper
|
||||
}
|
||||
|
||||
+ public static long blockToSection(long i) { return e(i); } // Paper - OBFHELPER
|
||||
public static long e(long i) {
|
||||
- return b(a(BlockPosition.b(i)), a(BlockPosition.c(i)), a(BlockPosition.d(i)));
|
||||
+ // b(a(BlockPosition.b(i)), a(BlockPosition.c(i)), a(BlockPosition.d(i)));
|
||||
+ return (((long) (int) (i >> 42) & 4194303L) << 42) | (((long) (int) ((i << 52) >> 56) & 1048575L)) | (((long) (int) ((i << 26) >> 42) & 4194303L) << 20); // Simplify to reduce instruction count
|
||||
}
|
||||
|
||||
public static long f(long i) {
|
||||
@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
}
|
||||
|
||||
public BlockPosition s() {
|
||||
- return new BlockPosition(c(this.a()), c(this.b()), c(this.c()));
|
||||
+ return new BlockPosition(x << 4, y << 4, z << 4); // Paper
|
||||
}
|
||||
|
||||
public BlockPosition t() {
|
||||
@@ -0,0 +0,0 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
return new ChunkCoordIntPair(this.a(), this.c());
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public static long blockPosAsSectionLong(int i, int j, int k) {
|
||||
+ return (((long) (i >> 4) & 4194303L) << 42) | (((long) (j >> 4) & 1048575L)) | (((long) (k >> 4) & 4194303L) << 20);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ public static long asLong(int i, int j, int k) { return b(i, j, k); } // Paper - OBFHELPER
|
||||
public static long b(int i, int j, int k) {
|
||||
- long l = 0L;
|
||||
-
|
||||
- l |= ((long) i & 4194303L) << 42;
|
||||
- l |= ((long) j & 1048575L) << 0;
|
||||
- l |= ((long) k & 4194303L) << 20;
|
||||
- return l;
|
||||
+ return (((long) i & 4194303L) << 42) | (((long) j & 1048575L)) | (((long) k & 4194303L) << 20); // Paper - Simplify to reduce instruction count
|
||||
}
|
||||
|
||||
public long v() {
|
||||
- return b(this.a(), this.b(), this.c());
|
||||
+ return (((long) x & 4194303L) << 42) | (((long) y & 1048575L)) | (((long) z & 4194303L) << 20); // Paper - Simplify to reduce instruction count
|
||||
}
|
||||
|
||||
public Stream<BlockPosition> w() {
|
||||
- return BlockPosition.a(this.d(), this.e(), this.f(), this.g(), this.h(), this.r());
|
||||
+ return BlockPosition.a(x << 4, y << 4, z << 4, (x << 4) + 15, (y << 4) + 15, (z << 4) + 15); // Paper - simplify/inline
|
||||
}
|
||||
|
||||
public static Stream<SectionPosition> a(SectionPosition sectionposition, int i) {
|
||||
- int j = sectionposition.a();
|
||||
- int k = sectionposition.b();
|
||||
- int l = sectionposition.c();
|
||||
-
|
||||
- return a(j - i, k - i, l - i, j + i, k + i, l + i);
|
||||
+ return a(sectionposition.x - i, sectionposition.y - i, sectionposition.z - i, sectionposition.x + i, sectionposition.y + i, sectionposition.z + i); // Paper - simplify/inline
|
||||
}
|
||||
|
||||
public static Stream<SectionPosition> b(ChunkCoordIntPair chunkcoordintpair, int i) {
|
||||
- int j = chunkcoordintpair.x;
|
||||
- int k = chunkcoordintpair.z;
|
||||
-
|
||||
- return a(j - i, 0, k - i, j + i, 15, k + i);
|
||||
+ return a(chunkcoordintpair.x - i, 0, chunkcoordintpair.z - i, chunkcoordintpair.x + i, 15, chunkcoordintpair.z + i); // Paper - simplify/inline
|
||||
}
|
||||
|
||||
public static Stream<SectionPosition> a(final int i, final int j, final int k, final int l, final int i1, final int j1) {
|
1213
Spigot-Server-Patches/Optimize-Light-Engine.patch
Normal file
1213
Spigot-Server-Patches/Optimize-Light-Engine.patch
Normal file
File diff suppressed because it is too large
Load diff
|
@ -40,8 +40,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
protected void a(LightEngineLayer<?, ?> lightenginelayer, long i) {
|
||||
@@ -0,0 +0,0 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
||||
|
||||
protected void a(long i, @Nullable NibbleArray nibblearray) {
|
||||
if (nibblearray != null) {
|
||||
this.i.put(i, nibblearray);
|
||||
- this.i.put(i, nibblearray);
|
||||
+ NibbleArray remove = this.i.put(i, nibblearray); if (remove != null && remove.cleaner != null) remove.cleaner.run(); // Paper - clean up when removed
|
||||
} else {
|
||||
- this.i.remove(i);
|
||||
+ NibbleArray remove = this.i.remove(i); if (remove != null && remove.cleaner != null) remove.cleaner.run(); // Paper - clean up when removed
|
||||
|
@ -59,7 +62,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
- this.data.queueUpdate(i, ((NibbleArray) this.data.getUpdating(i)).b()); // Paper - avoid copying light data
|
||||
+ NibbleArray updating = this.data.getUpdating(i); // Paper - pool nibbles
|
||||
+ this.data.queueUpdate(i, new NibbleArray().markPoolSafe(updating.getCloneIfSet())); // Paper - avoid copying light data - pool safe clone
|
||||
+ if (updating.cleaner != null) updating.cleaner.run(); // Paper
|
||||
+ if (updating.cleaner != null) MCUtil.scheduleTask(2, updating.cleaner); // Paper - delay clean incase anything holding ref was still using it
|
||||
this.c();
|
||||
}
|
||||
|
||||
|
@ -262,7 +265,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ public void onPacketDispatchFinish(EntityPlayer player, io.netty.channel.ChannelFuture future) {
|
||||
+ if (remainingSends.decrementAndGet() <= 0) {
|
||||
+ // incase of any race conditions, schedule this delayed
|
||||
+ MCUtil.scheduleTask(1, () -> {
|
||||
+ MCUtil.scheduleTask(5, () -> {
|
||||
+ if (remainingSends.get() == 0) {
|
||||
+ cleaner1.run();
|
||||
+ cleaner2.run();
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 3 Mar 2016 02:07:55 -0600
|
||||
Subject: [PATCH] Optimize isValidLocation, getType and getBlockData for inling
|
||||
Subject: [PATCH] Optimize isValidLocation, getType and getBlockData for
|
||||
inlining
|
||||
|
||||
Hot methods, so reduce # of instructions for the method.
|
||||
|
||||
|
@ -47,28 +48,60 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
- int k = blockposition.getZ();
|
||||
+ return this.getBlockData(blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
||||
+ }
|
||||
|
||||
+
|
||||
+ public IBlockData getType(final int x, final int y, final int z) {
|
||||
+ return getBlockData(x, y, z);
|
||||
+ }
|
||||
+ public final IBlockData getBlockData(final int x, final int y, final int z) {
|
||||
+ // Method body / logic copied from below
|
||||
+ final int i = y >> 4;
|
||||
+ if (y >= 0 && i < this.sections.length && this.sections[i] != null) {
|
||||
+ // Inlined ChunkSection.getType() and DataPaletteBlock.a(int,int,int)
|
||||
+ return this.sections[i].blockIds.a((y & 15) << 8 | (z & 15) << 4 | x & 15);
|
||||
+ if (y < 0 || i >= this.sections.length || this.sections[i] == null || this.sections[i].nonEmptyBlockCount == 0) {
|
||||
+ return Blocks.AIR.getBlockData();
|
||||
+ }
|
||||
+ return Blocks.AIR.getBlockData();
|
||||
+ // Inlined ChunkSection.getType() and DataPaletteBlock.a(int,int,int)
|
||||
+ return this.sections[i].blockIds.a((y & 15) << 8 | (z & 15) << 4 | x & 15);
|
||||
+ }
|
||||
+
|
||||
|
||||
+ public IBlockData getBlockData_unused(int i, int j, int k) {
|
||||
+ // Paper end
|
||||
if (this.world.P() == WorldType.DEBUG_ALL_BLOCK_STATES) {
|
||||
IBlockData iblockdata = null;
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkEmpty.java b/src/main/java/net/minecraft/server/ChunkEmpty.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkEmpty.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkEmpty.java
|
||||
@@ -0,0 +0,0 @@ import javax.annotation.Nullable;
|
||||
|
||||
public class ChunkEmpty extends Chunk {
|
||||
|
||||
- private static final BiomeBase[] b = (BiomeBase[]) SystemUtils.a((Object) (new BiomeBase[BiomeStorage.a]), (abiomebase) -> {
|
||||
+ private static final BiomeBase[] b = (BiomeBase[]) SystemUtils.a((new BiomeBase[BiomeStorage.a]), (abiomebase) -> { // Paper - decompile error
|
||||
Arrays.fill(abiomebase, Biomes.PLAINS);
|
||||
});
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ChunkEmpty extends Chunk {
|
||||
super(world, chunkcoordintpair, new BiomeStorage(ChunkEmpty.b));
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override public IBlockData getType(int x, int y, int z) {
|
||||
+ return Blocks.VOID_AIR.getBlockData();
|
||||
+ }
|
||||
+ // Paper end
|
||||
@Override
|
||||
public IBlockData getType(BlockPosition blockposition) {
|
||||
return Blocks.VOID_AIR.getBlockData();
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkSection.java b/src/main/java/net/minecraft/server/ChunkSection.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkSection.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkSection.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkSection {
|
||||
private short nonEmptyBlockCount;
|
||||
|
||||
public static final DataPalette<IBlockData> GLOBAL_PALETTE = new DataPaletteGlobal<>(Block.REGISTRY_ID, Blocks.AIR.getBlockData());
|
||||
private final int yPos;
|
||||
- private short nonEmptyBlockCount;
|
||||
+ short nonEmptyBlockCount; // Paper - package-private
|
||||
private short tickingBlockCount;
|
||||
private short e;
|
||||
- private final DataPaletteBlock<IBlockData> blockIds;
|
||||
|
@ -76,6 +109,87 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
public ChunkSection(int i) {
|
||||
this(i, (short) 0, (short) 0, (short) 0);
|
||||
@@ -0,0 +0,0 @@ public class ChunkSection {
|
||||
this.blockIds = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, Block.REGISTRY_ID, GameProfileSerializer::d, GameProfileSerializer::a, Blocks.AIR.getBlockData());
|
||||
}
|
||||
|
||||
- public IBlockData getType(int i, int j, int k) {
|
||||
- return (IBlockData) this.blockIds.a(i, j, k);
|
||||
+ public final IBlockData getType(int i, int j, int k) { // Paper
|
||||
+ return this.blockIds.a(j << 8 | k << 4 | i); // Paper - inline
|
||||
}
|
||||
|
||||
public Fluid b(int i, int j, int k) {
|
||||
diff --git a/src/main/java/net/minecraft/server/DataPaletteBlock.java b/src/main/java/net/minecraft/server/DataPaletteBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/DataPaletteBlock.java
|
||||
+++ b/src/main/java/net/minecraft/server/DataPaletteBlock.java
|
||||
@@ -0,0 +0,0 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
|
||||
}
|
||||
|
||||
public T a(int i, int j, int k) {
|
||||
- return this.a(b(i, j, k));
|
||||
+ return this.a(j << 8 | k << 4 | i); // Paper - inline
|
||||
}
|
||||
|
||||
protected T a(int i) {
|
||||
diff --git a/src/main/java/net/minecraft/server/IChunkAccess.java b/src/main/java/net/minecraft/server/IChunkAccess.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/IChunkAccess.java
|
||||
+++ b/src/main/java/net/minecraft/server/IChunkAccess.java
|
||||
@@ -0,0 +0,0 @@ import org.apache.logging.log4j.LogManager;
|
||||
|
||||
public interface IChunkAccess extends IBlockAccess, IStructureAccess {
|
||||
|
||||
+ IBlockData getType(final int x, final int y, final int z); // Paper
|
||||
@Nullable
|
||||
IBlockData setType(BlockPosition blockposition, IBlockData iblockdata, boolean flag);
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/ProtoChunk.java b/src/main/java/net/minecraft/server/ProtoChunk.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/ProtoChunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/ProtoChunk.java
|
||||
@@ -0,0 +0,0 @@ public class ProtoChunk implements IChunkAccess {
|
||||
|
||||
@Override
|
||||
public IBlockData getType(BlockPosition blockposition) {
|
||||
- int i = blockposition.getY();
|
||||
-
|
||||
- if (World.b(i)) {
|
||||
+ return getType(blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
||||
+ }
|
||||
+ // Paper start
|
||||
+ public IBlockData getType(final int x, final int y, final int z) {
|
||||
+ if (y < 0 || y >= 256) {
|
||||
return Blocks.VOID_AIR.getBlockData();
|
||||
} else {
|
||||
- ChunkSection chunksection = this.getSections()[i >> 4];
|
||||
-
|
||||
- return ChunkSection.a(chunksection) ? Blocks.AIR.getBlockData() : chunksection.getType(blockposition.getX() & 15, i & 15, blockposition.getZ() & 15);
|
||||
+ ChunkSection chunksection = this.getSections()[y >> 4];
|
||||
+ return chunksection == Chunk.EMPTY_CHUNK_SECTION || chunksection.c() ? Blocks.AIR.getBlockData() : chunksection.getType(x & 15, y & 15, z & 15);
|
||||
}
|
||||
}
|
||||
+ // Paper end
|
||||
|
||||
@Override
|
||||
public Fluid getFluid(BlockPosition blockposition) {
|
||||
diff --git a/src/main/java/net/minecraft/server/ProtoChunkExtension.java b/src/main/java/net/minecraft/server/ProtoChunkExtension.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/ProtoChunkExtension.java
|
||||
+++ b/src/main/java/net/minecraft/server/ProtoChunkExtension.java
|
||||
@@ -0,0 +0,0 @@ public class ProtoChunkExtension extends ProtoChunk {
|
||||
public IBlockData getType(BlockPosition blockposition) {
|
||||
return this.a.getType(blockposition);
|
||||
}
|
||||
+ // Paper start
|
||||
+ public final IBlockData getType(final int x, final int y, final int z) {
|
||||
+ return this.a.getBlockData(x, y, z);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
@Override
|
||||
public Fluid getFluid(BlockPosition blockposition) {
|
||||
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/World.java
|
||||
|
|
|
@ -3,58 +3,48 @@ From: Spottedleaf <spottedleaf@spottedleaf.dev>
|
|||
Date: Mon, 27 Apr 2020 02:48:06 -0700
|
||||
Subject: [PATCH] Reduce MutableInt allocations from light engine
|
||||
|
||||
We can abuse the fact light is single threaded and share an instance
|
||||
per light engine instance
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/LightEngineBlock.java b/src/main/java/net/minecraft/server/LightEngineBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/LightEngineBlock.java
|
||||
+++ b/src/main/java/net/minecraft/server/LightEngineBlock.java
|
||||
@@ -0,0 +0,0 @@ public final class LightEngineBlock extends LightEngineLayer<LightEngineStorageB
|
||||
|
||||
private static final EnumDirection[] e = EnumDirection.values();
|
||||
private final BlockPosition.MutableBlockPosition f = new BlockPosition.MutableBlockPosition();
|
||||
+ private final MutableInt mutableint = new MutableInt(); // Paper
|
||||
|
||||
public LightEngineBlock(ILightAccess ilightaccess) {
|
||||
super(ilightaccess, EnumSkyBlock.BLOCK, new LightEngineStorageBlock(ilightaccess));
|
||||
@@ -0,0 +0,0 @@ public final class LightEngineBlock extends LightEngineLayer<LightEngineStorageB
|
||||
if (enumdirection == null) {
|
||||
return 15;
|
||||
} else {
|
||||
- MutableInt mutableint = new MutableInt();
|
||||
+ // Paper start - reduce mutableint allocations
|
||||
+ MutableInt mutableint = com.destroystokyo.paper.util.pooled.PooledObjects.POOLED_MUTABLE_INTEGERS.acquire();
|
||||
+ try {
|
||||
+ // Paper end - reduce mutableint allocations
|
||||
+ //MutableInt mutableint = new MutableInt(); // Paper - share mutableint, single threaded
|
||||
IBlockData iblockdata = this.a(j, mutableint);
|
||||
|
||||
if (mutableint.getValue() >= 15) {
|
||||
@@ -0,0 +0,0 @@ public final class LightEngineBlock extends LightEngineLayer<LightEngineStorageB
|
||||
|
||||
return VoxelShapes.b(voxelshape, voxelshape1) ? 15 : k + Math.max(1, mutableint.getValue());
|
||||
}
|
||||
+ } finally { // Paper start - reduce mutableint allocations
|
||||
+ com.destroystokyo.paper.util.pooled.PooledObjects.POOLED_MUTABLE_INTEGERS.release(mutableint);
|
||||
+ }
|
||||
+ // Paper end - reduce mutableint allocations
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/LightEngineSky.java b/src/main/java/net/minecraft/server/LightEngineSky.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/LightEngineSky.java
|
||||
+++ b/src/main/java/net/minecraft/server/LightEngineSky.java
|
||||
@@ -0,0 +0,0 @@ public final class LightEngineSky extends LightEngineLayer<LightEngineStorageSky
|
||||
|
||||
private static final EnumDirection[] e = EnumDirection.values();
|
||||
private static final EnumDirection[] f = new EnumDirection[]{EnumDirection.NORTH, EnumDirection.SOUTH, EnumDirection.WEST, EnumDirection.EAST};
|
||||
+ private final MutableInt mutableint = new MutableInt(); // Paper
|
||||
|
||||
public LightEngineSky(ILightAccess ilightaccess) {
|
||||
super(ilightaccess, EnumSkyBlock.SKY, new LightEngineStorageSky(ilightaccess));
|
||||
@@ -0,0 +0,0 @@ public final class LightEngineSky extends LightEngineLayer<LightEngineStorageSky
|
||||
if (k >= 15) {
|
||||
return k;
|
||||
} else {
|
||||
- MutableInt mutableint = new MutableInt();
|
||||
+ // Paper start - reduce mutableint allocations
|
||||
+ MutableInt mutableint = com.destroystokyo.paper.util.pooled.PooledObjects.POOLED_MUTABLE_INTEGERS.acquire();
|
||||
+ try {
|
||||
+ // Paper end - reduce mutableint allocations
|
||||
+ //MutableInt mutableint = new MutableInt(); // Paper - share mutableint, single threaded
|
||||
IBlockData iblockdata = this.a(j, mutableint);
|
||||
|
||||
if (mutableint.getValue() >= 15) {
|
||||
@@ -0,0 +0,0 @@ public final class LightEngineSky extends LightEngineLayer<LightEngineStorageSky
|
||||
|
||||
return flag1 && k == 0 && mutableint.getValue() == 0 ? 0 : k + Math.max(1, mutableint.getValue());
|
||||
}
|
||||
+ } finally { // Paper start - reduce mutableint allocations
|
||||
+ com.destroystokyo.paper.util.pooled.PooledObjects.POOLED_MUTABLE_INTEGERS.release(mutableint);
|
||||
+ }
|
||||
+ // Paper end - reduce mutableint allocations
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,34 +112,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@Nullable
|
||||
- public NibbleArray c(long i) {
|
||||
+ public final NibbleArray c(long i) { // Paper - final
|
||||
+ // Paper start - remove cache - not thread safe
|
||||
+ /*
|
||||
if (this.d) {
|
||||
for (int j = 0; j < 2; ++j) {
|
||||
if (i == this.b[j]) {
|
||||
return this.c[j];
|
||||
}
|
||||
}
|
||||
- }
|
||||
+ }*/
|
||||
+ // Paper end
|
||||
|
||||
- NibbleArray nibblearray = (NibbleArray) this.a.get(i);
|
||||
+ return lookup.apply(i); // Paper - avoid copying light data
|
||||
|
||||
+ // Paper start - remove cache - not thread safe
|
||||
+ /*
|
||||
if (nibblearray == null) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -0,0 +0,0 @@ public abstract class LightEngineStorageArray<M extends LightEngineStorageArray<
|
||||
}
|
||||
}
|
||||
|
||||
return nibblearray;
|
||||
- }
|
||||
+ }*/
|
||||
+ // Paper end
|
||||
}
|
||||
- NibbleArray nibblearray = (NibbleArray) this.a.get(i);
|
||||
+ NibbleArray nibblearray = lookup.apply(i); // Paper - avoid copying light data
|
||||
|
||||
if (nibblearray == null) {
|
||||
return null;
|
||||
@@ -0,0 +0,0 @@ public abstract class LightEngineStorageArray<M extends LightEngineStorageArray<
|
||||
|
||||
@Nullable
|
||||
public NibbleArray d(long i) {
|
||||
|
@ -155,13 +140,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
|
||||
public void c() {
|
||||
+ /* // Paper - remove cache
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
@@ -0,0 +0,0 @@ public abstract class LightEngineStorageArray<M extends LightEngineStorageArray<
|
||||
this.b[i] = Long.MAX_VALUE;
|
||||
this.c[i] = null;
|
||||
}
|
||||
-
|
||||
+ */
|
||||
}
|
||||
|
||||
public void d() {
|
||||
|
|
Loading…
Add table
Reference in a new issue