Paper/Spigot-Server-Patches/0032-Optimize-explosions.patch

152 lines
6.5 KiB
Diff
Raw Normal View History

From 756d58f146d9c136d05cb02edc280e5d68dbdab6 Mon Sep 17 00:00:00 2001
2015-06-16 12:55:15 +00:00
From: Byteflux <byte@byteflux.net>
2016-02-29 23:09:49 +00:00
Date: Wed, 2 Mar 2016 11:59:48 -0600
2015-06-16 12:55:15 +00:00
Subject: [PATCH] Optimize explosions
The process of determining an entity's exposure from explosions can be
expensive when there are hundreds or more entities in range.
This patch adds a per-tick cache that is used for storing and retrieving
an entity's exposure during an explosion.
2016-02-29 23:09:49 +00:00
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
Improve mid tick chunk loading, Fix Oversleep, other improvements Process loads outside of any canSleep check. Original intent was to only apply those restrictions to generations but realized I had some checks higher up the call chain. Reworked the back off strategy to just run every 1 millisecond per world, and to apply the per tick limit to generations only. This guarantees that your chunk will load with at most around 1ms delay. Additionally, fire midTick processing in a few more places, notably the oversleep section so we can keep processing loads here too which has a large up to 50ms window... Speaking of oversleep, we had a bug in our implementation changes for Timings that caused oversleep to not sleep the correct amount. Because we now moved it into the NEXT tick instead of THIS tick, the value of nextTick had already been increased to +50ms, resulting in the risk of sleeping more than it should, but, more importantly, this caused every task that was trying to NOT run during oversleep to actually run during oversleep. This is now fixed. Another small tweak is to the /tps command, to no longer show the star when TPS is right at 20. Due to ineffeciencies in the sleep precision, TPS is commonly 20.02. This causes the star to show up almost constantly, so now only show it if we actually hit a real "catchup". This commit also improves the changes to the CallbackExecutor, in that it now is also recursion safe. It was possible that the executor could run tasks out of desired order if the executor task scheduled more executor tasks. We solve this by ensuring new additions do not enter the currently iterated queue. Each depth level will have its own queue. Fixes #3220
2020-04-26 03:47:29 +00:00
index 50dec5cb5e..f038d3f7dc 100644
2016-02-29 23:09:49 +00:00
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -150,4 +150,10 @@ public class PaperWorldConfig {
disableEndCredits = getBoolean("game-mechanics.disable-end-credits", false);
log("End credits disabled: " + disableEndCredits);
2016-02-29 23:09:49 +00:00
}
+
+ public boolean optimizeExplosions;
+ private void optimizeExplosions() {
+ optimizeExplosions = getBoolean("optimize-explosions", false);
+ log("Optimize explosions: " + optimizeExplosions);
+ }
}
2015-06-16 12:55:15 +00:00
diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java
Improve mid tick chunk loading, Fix Oversleep, other improvements Process loads outside of any canSleep check. Original intent was to only apply those restrictions to generations but realized I had some checks higher up the call chain. Reworked the back off strategy to just run every 1 millisecond per world, and to apply the per tick limit to generations only. This guarantees that your chunk will load with at most around 1ms delay. Additionally, fire midTick processing in a few more places, notably the oversleep section so we can keep processing loads here too which has a large up to 50ms window... Speaking of oversleep, we had a bug in our implementation changes for Timings that caused oversleep to not sleep the correct amount. Because we now moved it into the NEXT tick instead of THIS tick, the value of nextTick had already been increased to +50ms, resulting in the risk of sleeping more than it should, but, more importantly, this caused every task that was trying to NOT run during oversleep to actually run during oversleep. This is now fixed. Another small tweak is to the /tps command, to no longer show the star when TPS is right at 20. Due to ineffeciencies in the sleep precision, TPS is commonly 20.02. This causes the star to show up almost constantly, so now only show it if we actually hit a real "catchup". This commit also improves the changes to the CallbackExecutor, in that it now is also recursion safe. It was possible that the executor could run tasks out of desired order if the executor task scheduled more executor tasks. We solve this by ensuring new additions do not enter the currently iterated queue. Each depth level will have its own queue. Fixes #3220
2020-04-26 03:47:29 +00:00
index a063d1bfaa..5583860f15 100644
2015-06-16 12:55:15 +00:00
--- a/src/main/java/net/minecraft/server/Explosion.java
+++ b/src/main/java/net/minecraft/server/Explosion.java
2019-12-11 00:56:03 +00:00
@@ -177,7 +177,7 @@ public class Explosion {
2015-06-16 12:55:15 +00:00
d8 /= d11;
d9 /= d11;
d10 /= d11;
2019-04-24 02:34:11 +00:00
- double d12 = (double) a(vec3d, entity);
+ double d12 = this.getBlockDensity(vec3d, entity); // Paper - Optimize explosions
2015-06-16 12:55:15 +00:00
double d13 = (1.0D - d7) * d12;
2016-02-29 23:09:49 +00:00
// CraftBukkit start
@@ -384,4 +384,84 @@ public class Explosion {
2019-04-24 02:34:11 +00:00
private Effect() {}
2015-06-16 12:55:15 +00:00
}
2016-02-29 23:09:49 +00:00
+ // Paper start - Optimize explosions
2019-04-24 02:34:11 +00:00
+ private float getBlockDensity(Vec3D vec3d, Entity entity) {
2016-02-29 23:09:49 +00:00
+ if (!this.world.paperConfig.optimizeExplosions) {
2019-04-24 02:34:11 +00:00
+ return a(vec3d, entity);
2015-06-16 12:55:15 +00:00
+ }
2019-04-24 02:34:11 +00:00
+ CacheKey key = new CacheKey(this, entity.getBoundingBox());
2015-06-16 12:55:15 +00:00
+ Float blockDensity = this.world.explosionDensityCache.get(key);
+ if (blockDensity == null) {
2019-04-24 02:34:11 +00:00
+ blockDensity = a(vec3d, entity);
2015-06-16 12:55:15 +00:00
+ this.world.explosionDensityCache.put(key, blockDensity);
+ }
+
+ return blockDensity;
+ }
+
+ static class CacheKey {
+ private final World world;
+ private final double posX, posY, posZ;
+ private final double minX, minY, minZ;
+ private final double maxX, maxY, maxZ;
+
+ public CacheKey(Explosion explosion, AxisAlignedBB aabb) {
+ this.world = explosion.world;
+ this.posX = explosion.posX;
+ this.posY = explosion.posY;
+ this.posZ = explosion.posZ;
2018-10-22 23:16:21 +00:00
+ this.minX = aabb.minX;
+ this.minY = aabb.minY;
+ this.minZ = aabb.minZ;
+ this.maxX = aabb.maxX;
+ this.maxY = aabb.maxY;
+ this.maxZ = aabb.maxZ;
2015-06-16 12:55:15 +00:00
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ CacheKey cacheKey = (CacheKey) o;
+
+ if (Double.compare(cacheKey.posX, posX) != 0) return false;
+ if (Double.compare(cacheKey.posY, posY) != 0) return false;
+ if (Double.compare(cacheKey.posZ, posZ) != 0) return false;
+ if (Double.compare(cacheKey.minX, minX) != 0) return false;
+ if (Double.compare(cacheKey.minY, minY) != 0) return false;
+ if (Double.compare(cacheKey.minZ, minZ) != 0) return false;
+ if (Double.compare(cacheKey.maxX, maxX) != 0) return false;
+ if (Double.compare(cacheKey.maxY, maxY) != 0) return false;
+ if (Double.compare(cacheKey.maxZ, maxZ) != 0) return false;
+ return world.equals(cacheKey.world);
+ }
+
+ @Override
+ public int hashCode() {
+ int result;
+ long temp;
+ result = world.hashCode();
+ temp = Double.doubleToLongBits(posX);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(posY);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(posZ);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(minX);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(minY);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(minZ);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(maxX);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(maxY);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(maxZ);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+ }
2016-02-29 23:09:49 +00:00
+ // Paper end
2015-06-16 12:55:15 +00:00
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
Improve mid tick chunk loading, Fix Oversleep, other improvements Process loads outside of any canSleep check. Original intent was to only apply those restrictions to generations but realized I had some checks higher up the call chain. Reworked the back off strategy to just run every 1 millisecond per world, and to apply the per tick limit to generations only. This guarantees that your chunk will load with at most around 1ms delay. Additionally, fire midTick processing in a few more places, notably the oversleep section so we can keep processing loads here too which has a large up to 50ms window... Speaking of oversleep, we had a bug in our implementation changes for Timings that caused oversleep to not sleep the correct amount. Because we now moved it into the NEXT tick instead of THIS tick, the value of nextTick had already been increased to +50ms, resulting in the risk of sleeping more than it should, but, more importantly, this caused every task that was trying to NOT run during oversleep to actually run during oversleep. This is now fixed. Another small tweak is to the /tps command, to no longer show the star when TPS is right at 20. Due to ineffeciencies in the sleep precision, TPS is commonly 20.02. This causes the star to show up almost constantly, so now only show it if we actually hit a real "catchup". This commit also improves the changes to the CallbackExecutor, in that it now is also recursion safe. It was possible that the executor could run tasks out of desired order if the executor task scheduled more executor tasks. We solve this by ensuring new additions do not enter the currently iterated queue. Each depth level will have its own queue. Fixes #3220
2020-04-26 03:47:29 +00:00
index 53d0a98d00..11f81ab364 100644
2015-06-16 12:55:15 +00:00
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
Improve mid tick chunk loading, Fix Oversleep, other improvements Process loads outside of any canSleep check. Original intent was to only apply those restrictions to generations but realized I had some checks higher up the call chain. Reworked the back off strategy to just run every 1 millisecond per world, and to apply the per tick limit to generations only. This guarantees that your chunk will load with at most around 1ms delay. Additionally, fire midTick processing in a few more places, notably the oversleep section so we can keep processing loads here too which has a large up to 50ms window... Speaking of oversleep, we had a bug in our implementation changes for Timings that caused oversleep to not sleep the correct amount. Because we now moved it into the NEXT tick instead of THIS tick, the value of nextTick had already been increased to +50ms, resulting in the risk of sleeping more than it should, but, more importantly, this caused every task that was trying to NOT run during oversleep to actually run during oversleep. This is now fixed. Another small tweak is to the /tps command, to no longer show the star when TPS is right at 20. Due to ineffeciencies in the sleep precision, TPS is commonly 20.02. This causes the star to show up almost constantly, so now only show it if we actually hit a real "catchup". This commit also improves the changes to the CallbackExecutor, in that it now is also recursion safe. It was possible that the executor could run tasks out of desired order if the executor task scheduled more executor tasks. We solve this by ensuring new additions do not enter the currently iterated queue. Each depth level will have its own queue. Fixes #3220
2020-04-26 03:47:29 +00:00
@@ -1181,6 +1181,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
2019-04-24 02:34:11 +00:00
this.methodProfiler.exit();
this.methodProfiler.exit();
2016-02-29 23:09:49 +00:00
+ worldserver.explosionDensityCache.clear(); // Paper - Optimize explosions
}
}
2015-06-16 12:55:15 +00:00
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
Improve mid tick chunk loading, Fix Oversleep, other improvements Process loads outside of any canSleep check. Original intent was to only apply those restrictions to generations but realized I had some checks higher up the call chain. Reworked the back off strategy to just run every 1 millisecond per world, and to apply the per tick limit to generations only. This guarantees that your chunk will load with at most around 1ms delay. Additionally, fire midTick processing in a few more places, notably the oversleep section so we can keep processing loads here too which has a large up to 50ms window... Speaking of oversleep, we had a bug in our implementation changes for Timings that caused oversleep to not sleep the correct amount. Because we now moved it into the NEXT tick instead of THIS tick, the value of nextTick had already been increased to +50ms, resulting in the risk of sleeping more than it should, but, more importantly, this caused every task that was trying to NOT run during oversleep to actually run during oversleep. This is now fixed. Another small tweak is to the /tps command, to no longer show the star when TPS is right at 20. Due to ineffeciencies in the sleep precision, TPS is commonly 20.02. This causes the star to show up almost constantly, so now only show it if we actually hit a real "catchup". This commit also improves the changes to the CallbackExecutor, in that it now is also recursion safe. It was possible that the executor could run tasks out of desired order if the executor task scheduled more executor tasks. We solve this by ensuring new additions do not enter the currently iterated queue. Each depth level will have its own queue. Fixes #3220
2020-04-26 03:47:29 +00:00
index 1bb3620154..4604634577 100644
2015-06-16 12:55:15 +00:00
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -80,6 +80,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
private org.spigotmc.TickLimiter entityLimiter;
private org.spigotmc.TickLimiter tileLimiter;
2015-06-16 12:55:15 +00:00
private int tileTickPosition;
+ public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
2015-06-16 12:55:15 +00:00
2016-02-29 23:09:49 +00:00
public CraftWorld getWorld() {
return this.world;
2015-06-16 12:55:15 +00:00
--
Improve mid tick chunk loading, Fix Oversleep, other improvements Process loads outside of any canSleep check. Original intent was to only apply those restrictions to generations but realized I had some checks higher up the call chain. Reworked the back off strategy to just run every 1 millisecond per world, and to apply the per tick limit to generations only. This guarantees that your chunk will load with at most around 1ms delay. Additionally, fire midTick processing in a few more places, notably the oversleep section so we can keep processing loads here too which has a large up to 50ms window... Speaking of oversleep, we had a bug in our implementation changes for Timings that caused oversleep to not sleep the correct amount. Because we now moved it into the NEXT tick instead of THIS tick, the value of nextTick had already been increased to +50ms, resulting in the risk of sleeping more than it should, but, more importantly, this caused every task that was trying to NOT run during oversleep to actually run during oversleep. This is now fixed. Another small tweak is to the /tps command, to no longer show the star when TPS is right at 20. Due to ineffeciencies in the sleep precision, TPS is commonly 20.02. This causes the star to show up almost constantly, so now only show it if we actually hit a real "catchup". This commit also improves the changes to the CallbackExecutor, in that it now is also recursion safe. It was possible that the executor could run tasks out of desired order if the executor task scheduled more executor tasks. We solve this by ensuring new additions do not enter the currently iterated queue. Each depth level will have its own queue. Fixes #3220
2020-04-26 03:47:29 +00:00
2.26.2
2015-06-16 12:55:15 +00:00