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 static final ThreadLocal<int[]> SPARSE = ThreadLocal.withInitial(() -> new int[1]);
|
||||||
|
|
||||||
private final PlaneSource source;
|
private final PlaneSource source;
|
||||||
|
private final ThreadLocal<Recent> recent = ThreadLocal.withInitial(Recent::new);
|
||||||
private volatile ConcurrentClockCache<ChunkPlanes> entries;
|
private volatile ConcurrentClockCache<ChunkPlanes> entries;
|
||||||
|
|
||||||
public ChunkBakeCache(PlaneSource source, int capacityChunks) {
|
public ChunkBakeCache(PlaneSource source, int capacityChunks) {
|
||||||
@@ -43,7 +44,9 @@ public final class ChunkBakeCache implements BakeCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
entries.clear();
|
ConcurrentClockCache<ChunkPlanes> current = entries;
|
||||||
|
entries = new ConcurrentClockCache<>(current.capacity());
|
||||||
|
current.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long[] census() {
|
public long[] census() {
|
||||||
@@ -71,8 +74,22 @@ public final class ChunkBakeCache implements BakeCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ChunkPlanes.Plane planeIfPresent(BakePlane plane, int chunkX, int chunkZ) {
|
public ChunkPlanes.Plane planeIfPresent(BakePlane plane, int chunkX, int chunkZ) {
|
||||||
ChunkPlanes planes = entries.get(key(chunkX, chunkZ));
|
long key = key(chunkX, chunkZ);
|
||||||
return planes == null ? null : planes.planeIfPresent(plane);
|
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) {
|
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) {
|
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() {
|
public boolean memoAllowed() {
|
||||||
@@ -91,14 +108,26 @@ public final class ChunkBakeCache implements BakeCache {
|
|||||||
if (revision != ProvisionalSampling.revision()) {
|
if (revision != ProvisionalSampling.revision()) {
|
||||||
return;
|
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) {
|
public void storeObject(BakePlane plane, int blockX, int blockZ, Object value, long revision) {
|
||||||
if (revision != ProvisionalSampling.revision()) {
|
if (revision != ProvisionalSampling.revision()) {
|
||||||
return;
|
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) {
|
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) {
|
public static long key(int chunkX, int chunkZ) {
|
||||||
return ((long) chunkX << 32) ^ (chunkZ & 0xffffffffL);
|
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);
|
double[] fractionZ = scratch.buffer(count);
|
||||||
scratch.clearLattice(count * 4);
|
scratch.clearLattice(count * 4);
|
||||||
int detailed = 0;
|
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++) {
|
for (int index = 0; index < count; index++) {
|
||||||
double lowerX = Math.floor(xs[index] / SURFACE_GRID) * SURFACE_GRID;
|
double lowerX = Math.floor(xs[index] / SURFACE_GRID) * SURFACE_GRID;
|
||||||
double lowerZ = Math.floor(zs[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;
|
double dz = (zs[index] - lowerZ) / SURFACE_GRID;
|
||||||
fractionX[index] = dx;
|
fractionX[index] = dx;
|
||||||
fractionZ[index] = dz;
|
fractionZ[index] = dz;
|
||||||
northWest[index] = scratch.lattice(lowerX, lowerZ);
|
if (Double.doubleToRawLongBits(lowerX) != Double.doubleToRawLongBits(previousX)
|
||||||
northEast[index] = dx == 0D ? -1 : scratch.lattice(lowerX + SURFACE_GRID, lowerZ);
|
|| Double.doubleToRawLongBits(lowerZ) != Double.doubleToRawLongBits(previousZ)) {
|
||||||
southWest[index] = dz == 0D ? -1 : scratch.lattice(lowerX, lowerZ + SURFACE_GRID);
|
previousX = lowerX;
|
||||||
southEast[index] = dx == 0D || dz == 0D ? -1 : scratch.lattice(lowerX + SURFACE_GRID, lowerZ + SURFACE_GRID);
|
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) {
|
if (dx != 0D || dz != 0D) {
|
||||||
detailed++;
|
detailed++;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user