mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-26 14:00:26 +00:00
Recent bake entry fast path
- Facade reads reuse the thread's last chunk entry instead of probing the bake map - Stores and full-chunk fills refresh that entry from the map - Surface lattice lookups reuse the previous point's cell indices
This commit is contained in:
1 parent
2bfa9c4528
commit
fa996a2e24
2 files changed
+69
-10
No files matched your search
@@ -10,6 +10,7 @@ public final class ChunkBakeCache implements BakeCache {
|
||||
private static final ThreadLocal<int[]> SPARSE = ThreadLocal.withInitial(() -> new int[1]);
|
||||
|
||||
private final PlaneSource source;
|
||||
private final ThreadLocal<Recent> recent = ThreadLocal.withInitial(Recent::new);
|
||||
private volatile ConcurrentClockCache<ChunkPlanes> entries;
|
||||
|
||||
public ChunkBakeCache(PlaneSource source, int capacityChunks) {
|
||||
@@ -43,7 +44,9 @@ public final class ChunkBakeCache implements BakeCache {
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
entries.clear();
|
||||
ConcurrentClockCache<ChunkPlanes> current = entries;
|
||||
entries = new ConcurrentClockCache<>(current.capacity());
|
||||
current.clear();
|
||||
}
|
||||
|
||||
public long[] census() {
|
||||
@@ -71,8 +74,22 @@ public final class ChunkBakeCache implements BakeCache {
|
||||
}
|
||||
|
||||
public ChunkPlanes.Plane planeIfPresent(BakePlane plane, int chunkX, int chunkZ) {
|
||||
ChunkPlanes planes = entries.get(key(chunkX, chunkZ));
|
||||
return planes == null ? null : planes.planeIfPresent(plane);
|
||||
long key = key(chunkX, chunkZ);
|
||||
Recent last = recent.get();
|
||||
ConcurrentClockCache<ChunkPlanes> current = entries;
|
||||
ChunkPlanes planes;
|
||||
if (last.key == key && last.entries == current) {
|
||||
planes = last.planes;
|
||||
} else {
|
||||
planes = current.get(key);
|
||||
if (planes == null) {
|
||||
return null;
|
||||
}
|
||||
last.key = key;
|
||||
last.planes = planes;
|
||||
last.entries = current;
|
||||
}
|
||||
return planes.planeIfPresent(plane);
|
||||
}
|
||||
|
||||
public ChunkPlanes.Plane plane(BakePlane plane, int chunkX, int chunkZ) {
|
||||
@@ -80,7 +97,7 @@ public final class ChunkBakeCache implements BakeCache {
|
||||
}
|
||||
|
||||
public Object complete(BakePlane plane, int chunkX, int chunkZ) {
|
||||
return planes(chunkX, chunkZ).complete(plane, source);
|
||||
return remembered(chunkX, chunkZ).complete(plane, source);
|
||||
}
|
||||
|
||||
public boolean memoAllowed() {
|
||||
@@ -91,14 +108,26 @@ public final class ChunkBakeCache implements BakeCache {
|
||||
if (revision != ProvisionalSampling.revision()) {
|
||||
return;
|
||||
}
|
||||
planes(blockX >> 4, blockZ >> 4).plane(plane).storeDouble(((blockZ & 15) << 4) | (blockX & 15), value);
|
||||
remembered(blockX >> 4, blockZ >> 4).plane(plane).storeDouble(((blockZ & 15) << 4) | (blockX & 15), value);
|
||||
}
|
||||
|
||||
public void storeObject(BakePlane plane, int blockX, int blockZ, Object value, long revision) {
|
||||
if (revision != ProvisionalSampling.revision()) {
|
||||
return;
|
||||
}
|
||||
planes(blockX >> 4, blockZ >> 4).plane(plane).storeObject(((blockZ & 15) << 4) | (blockX & 15), value);
|
||||
remembered(blockX >> 4, blockZ >> 4).plane(plane).storeObject(((blockZ & 15) << 4) | (blockX & 15), value);
|
||||
}
|
||||
|
||||
private ChunkPlanes remembered(int chunkX, int chunkZ) {
|
||||
ConcurrentClockCache<ChunkPlanes> current = entries;
|
||||
long key = key(chunkX, chunkZ);
|
||||
ChunkPlanes existing = current.get(key);
|
||||
ChunkPlanes planes = existing != null ? existing : current.putIfAbsent(key, new ChunkPlanes(chunkX, chunkZ));
|
||||
Recent last = recent.get();
|
||||
last.key = key;
|
||||
last.planes = planes;
|
||||
last.entries = current;
|
||||
return planes;
|
||||
}
|
||||
|
||||
public static <T> T sparse(Supplier<T> action) {
|
||||
@@ -125,4 +154,10 @@ public final class ChunkBakeCache implements BakeCache {
|
||||
public static long key(int chunkX, int chunkZ) {
|
||||
return ((long) chunkX << 32) ^ (chunkZ & 0xffffffffL);
|
||||
}
|
||||
|
||||
private static final class Recent {
|
||||
private long key;
|
||||
private ChunkPlanes planes;
|
||||
private ConcurrentClockCache<ChunkPlanes> entries;
|
||||
}
|
||||
}
|
||||
@@ -69,6 +69,12 @@ public final class GeneratorProgram {
|
||||
double[] fractionZ = scratch.buffer(count);
|
||||
scratch.clearLattice(count * 4);
|
||||
int detailed = 0;
|
||||
double previousX = Double.NaN;
|
||||
double previousZ = Double.NaN;
|
||||
int cellNorthWest = -1;
|
||||
int cellNorthEast = -1;
|
||||
int cellSouthWest = -1;
|
||||
int cellSouthEast = -1;
|
||||
for (int index = 0; index < count; index++) {
|
||||
double lowerX = Math.floor(xs[index] / SURFACE_GRID) * SURFACE_GRID;
|
||||
double lowerZ = Math.floor(zs[index] / SURFACE_GRID) * SURFACE_GRID;
|
||||
@@ -76,10 +82,28 @@ public final class GeneratorProgram {
|
||||
double dz = (zs[index] - lowerZ) / SURFACE_GRID;
|
||||
fractionX[index] = dx;
|
||||
fractionZ[index] = dz;
|
||||
northWest[index] = scratch.lattice(lowerX, lowerZ);
|
||||
northEast[index] = dx == 0D ? -1 : scratch.lattice(lowerX + SURFACE_GRID, lowerZ);
|
||||
southWest[index] = dz == 0D ? -1 : scratch.lattice(lowerX, lowerZ + SURFACE_GRID);
|
||||
southEast[index] = dx == 0D || dz == 0D ? -1 : scratch.lattice(lowerX + SURFACE_GRID, lowerZ + SURFACE_GRID);
|
||||
if (Double.doubleToRawLongBits(lowerX) != Double.doubleToRawLongBits(previousX)
|
||||
|| Double.doubleToRawLongBits(lowerZ) != Double.doubleToRawLongBits(previousZ)) {
|
||||
previousX = lowerX;
|
||||
previousZ = lowerZ;
|
||||
cellNorthWest = scratch.lattice(lowerX, lowerZ);
|
||||
cellNorthEast = -1;
|
||||
cellSouthWest = -1;
|
||||
cellSouthEast = -1;
|
||||
}
|
||||
if (dx != 0D && cellNorthEast < 0) {
|
||||
cellNorthEast = scratch.lattice(lowerX + SURFACE_GRID, lowerZ);
|
||||
}
|
||||
if (dz != 0D && cellSouthWest < 0) {
|
||||
cellSouthWest = scratch.lattice(lowerX, lowerZ + SURFACE_GRID);
|
||||
}
|
||||
if (dx != 0D && dz != 0D && cellSouthEast < 0) {
|
||||
cellSouthEast = scratch.lattice(lowerX + SURFACE_GRID, lowerZ + SURFACE_GRID);
|
||||
}
|
||||
northWest[index] = cellNorthWest;
|
||||
northEast[index] = dx == 0D ? -1 : cellNorthEast;
|
||||
southWest[index] = dz == 0D ? -1 : cellSouthWest;
|
||||
southEast[index] = dx == 0D || dz == 0D ? -1 : cellSouthEast;
|
||||
if (dx != 0D || dz != 0D) {
|
||||
detailed++;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user