This commit is contained in:
Daniel Mills 2020-12-30 08:31:23 -05:00
parent e926a08def
commit 634e7ad7ee
2 changed files with 61 additions and 41 deletions

View File

@ -29,6 +29,8 @@ import java.nio.file.Paths;
import java.util.Comparator; import java.util.Comparator;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
@Data @Data
@ -53,14 +55,32 @@ public class Pregenerator implements Listener
private final KList<ChunkPosition> mcaDefer; private final KList<ChunkPosition> mcaDefer;
private final AtomicInteger generated; private final AtomicInteger generated;
private final AtomicInteger generatedLast; private final AtomicInteger generatedLast;
private final AtomicInteger perSecond; private final RollingSequence perSecond;
private final AtomicInteger totalChunks;
private final AtomicLong memory;
private final AtomicReference<String> memoryMetric;
private final AtomicReference<String> method;
private final AtomicInteger vmcax;
private final AtomicInteger vmcaz;
private final AtomicInteger vcax;
private final AtomicInteger vcaz;
private final long elapsed;
public Pregenerator(World world, int blockSize, int xoffset, int zoffset) public Pregenerator(World world, int blockSize, int xoffset, int zoffset)
{ {
instance(); instance();
elapsed = M.ms();
memoryMetric = new AtomicReference<>("...");
method = new AtomicReference<>("IDLE");
memory = new AtomicLong(0);
this.world = world; this.world = world;
perSecond = new AtomicInteger(0); vmcax = new AtomicInteger();
vmcaz = new AtomicInteger();
vcax = new AtomicInteger();
vcaz = new AtomicInteger();
perSecond = new RollingSequence(20);
generatedLast = new AtomicInteger(0); generatedLast = new AtomicInteger(0);
totalChunks = new AtomicInteger(0);
generated = new AtomicInteger(0); generated = new AtomicInteger(0);
mcaDefer = new KList<>(); mcaDefer = new KList<>();
IrisAccess access = IrisWorlds.access(world); IrisAccess access = IrisWorlds.access(world);
@ -77,6 +97,7 @@ public class Pregenerator implements Listener
min.setZ(Math.min(zz << 5, min.getZ())); min.setZ(Math.min(zz << 5, min.getZ()));
max.setX(Math.max((xx << 5) + 31, max.getX())); max.setX(Math.max((xx << 5) + 31, max.getX()));
max.setZ(Math.max((zz << 5) + 31, max.getZ())); max.setZ(Math.max((zz << 5) + 31, max.getZ()));
totalChunks.getAndAdd(1024);
}).drain(); }).drain();
gui = IrisSettings.get().isLocalPregenGui() && IrisSettings.get().isUseServerLaunchedGuis() ? MCAPregenGui.createAndShowGUI(this) : null; gui = IrisSettings.get().isLocalPregenGui() && IrisSettings.get().isUseServerLaunchedGuis() ? MCAPregenGui.createAndShowGUI(this) : null;
KList<ChunkPosition> order = computeChunkOrder(); KList<ChunkPosition> order = computeChunkOrder();
@ -84,6 +105,8 @@ public class Pregenerator implements Listener
(ox, oz, r) -> order.forEach((i) (ox, oz, r) -> order.forEach((i)
-> r.accept(i.getX() + ox, i.getZ() + oz)); -> r.accept(i.getX() + ox, i.getZ() + oz));
Spiraler spiraler = new Spiraler(mcaSize, mcaSize, (xx,zz) -> { Spiraler spiraler = new Spiraler(mcaSize, mcaSize, (xx,zz) -> {
vmcax.set(xx);
vmcaz.set(zz);
flushWorld(); flushWorld();
drawMCA(xx, zz, COLOR_MCA_PREPARE); drawMCA(xx, zz, COLOR_MCA_PREPARE);
if(generateMCARegion(xx, zz, burst, access, mcaIteration)) if(generateMCARegion(xx, zz, burst, access, mcaIteration))
@ -110,6 +133,8 @@ public class Pregenerator implements Listener
while(running.get() && mcaDefer.isNotEmpty()) while(running.get() && mcaDefer.isNotEmpty())
{ {
ChunkPosition p = mcaDefer.popLast(); ChunkPosition p = mcaDefer.popLast();
vmcax.set(p.getX());
vmcaz.set(p.getZ());
generateDeferedMCARegion(p.getX(), p.getZ(), burst, access, mcaIteration); generateDeferedMCARegion(p.getX(), p.getZ(), burst, access, mcaIteration);
drawMCA(p.getX(), p.getZ(), COLOR_MCA_SEALING); drawMCA(p.getX(), p.getZ(), COLOR_MCA_SEALING);
flushWorld(); flushWorld();
@ -134,10 +159,22 @@ public class Pregenerator implements Listener
int w = generatedLast.get(); int w = generatedLast.get();
int up = m - w; int up = m - w;
double dur = p.getMilliseconds(); double dur = p.getMilliseconds();
perSecond.set((int) (up / (dur / 1000D))); perSecond.put((int) (up / (dur / 1000D)));
p.reset(); p.reset();
p.begin(); p.begin();
generatedLast.set(m); generatedLast.set(m);
J.sleep(100);
long lmem = memory.get();
memory.set(Runtime.getRuntime().freeMemory());
if(memory.get() > lmem)
{
long free = memory.get();
long max = Runtime.getRuntime().maxMemory();
long total = Runtime.getRuntime().totalMemory();
long use = total - free;
memoryMetric.set(Form.memSize(use, 2) + " (" + Form.pc((double)use / (double)max, 0) + ")");
}
} }
}).start(); }).start();
} }
@ -152,11 +189,14 @@ public class Pregenerator implements Listener
int mcaoz = z << 5; int mcaoz = z << 5;
if(isMCAWritable(x,z) && !mca.exists()) if(isMCAWritable(x,z) && !mca.exists())
{ {
method.set("Direct (Fast)");
mcaIteration.accept(mcaox, mcaoz, (ii, jj) -> e.queue(() -> { mcaIteration.accept(mcaox, mcaoz, (ii, jj) -> e.queue(() -> {
draw(ii, jj, COLOR_MCA_GENERATE); draw(ii, jj, COLOR_MCA_GENERATE);
access.directWriteChunk(world, ii, jj, directWriter); access.directWriteChunk(world, ii, jj, directWriter);
draw(ii, jj, COLOR_MCA_GENERATED); draw(ii, jj, COLOR_MCA_GENERATED);
generated.getAndIncrement(); generated.getAndIncrement();
vcax.set(ii);
vcaz.set(jj);
})); }));
e.complete(); e.complete();
directWriter.flush(); directWriter.flush();
@ -184,11 +224,14 @@ public class Pregenerator implements Listener
if(PaperLib.isPaper()) if(PaperLib.isPaper())
{ {
method.set("PaperAsync (Slow)");
mcaIteration.accept(mcaox, mcaoz, (ii, jj) -> e.queue(() -> { mcaIteration.accept(mcaox, mcaoz, (ii, jj) -> e.queue(() -> {
draw(ii, jj, COLOR_MCA_GENERATE_SLOW); draw(ii, jj, COLOR_MCA_GENERATE_SLOW);
access.generatePaper(world, ii, jj); access.generatePaper(world, ii, jj);
draw(ii, jj, COLOR_MCA_GENERATED); draw(ii, jj, COLOR_MCA_GENERATED);
generated.getAndIncrement(); generated.getAndIncrement();
vcax.set(ii);
vcaz.set(jj);
})); }));
e.complete(); e.complete();
} }
@ -196,6 +239,7 @@ public class Pregenerator implements Listener
else else
{ {
AtomicInteger m = new AtomicInteger(); AtomicInteger m = new AtomicInteger();
method.set("Spigot (Very Slow)");
mcaIteration.accept(mcaox, mcaoz, (ii, jj) -> { mcaIteration.accept(mcaox, mcaoz, (ii, jj) -> {
draw(ii, jj, COLOR_MCA_GENERATE_SLOW); draw(ii, jj, COLOR_MCA_GENERATE_SLOW);
J.s(() -> { J.s(() -> {
@ -203,6 +247,8 @@ public class Pregenerator implements Listener
draw(ii, jj, COLOR_MCA_GENERATED); draw(ii, jj, COLOR_MCA_GENERATED);
m.getAndIncrement(); m.getAndIncrement();
generated.getAndIncrement(); generated.getAndIncrement();
vcax.set(ii);
vcaz.set(jj);
}); });
}); });
@ -304,7 +350,7 @@ public class Pregenerator implements Listener
while(!b.get()) while(!b.get())
{ {
J.sleep(10); J.sleep(1);
} }
} }
@ -316,7 +362,6 @@ public class Pregenerator implements Listener
} }
world.save(); world.save();
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "save-all");
} }
private boolean isMCAWritable(int x, int z) { private boolean isMCAWritable(int x, int z) {
@ -338,7 +383,16 @@ public class Pregenerator implements Listener
} }
public String[] getProgress() { public String[] getProgress() {
return new String[]{"Chunks/s: " + perSecond.get(), "Generated: " + Form.f(generated.get())}; long eta = (long) ((totalChunks.get() - generated.get()) * ((double)(M.ms() - elapsed) / (double) generated.get()));
return new String[]{
"Progress : " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (" + Form.pc((double)generated.get() / (double)totalChunks.get(), 0) + ")",
"ETA : " + Form.duration(eta, 0),
"Chunks/s : " + Form.f((int)perSecond.getAverage()),
"Memory : " + memoryMetric.get(),
"Cursor : " + "MCA(" + vmcax.get() + ", " + vmcaz.get() + ") @ (" + vcax.get() + ", " + vcaz.get() + ")",
"Gen Mode : " + method.get(),
};
} }
public boolean paused() { public boolean paused() {

View File

@ -4,7 +4,6 @@ import com.volmit.iris.Iris;
import com.volmit.iris.IrisSettings; import com.volmit.iris.IrisSettings;
import com.volmit.iris.manager.gui.PregenGui; import com.volmit.iris.manager.gui.PregenGui;
import com.volmit.iris.scaffold.IrisWorlds; import com.volmit.iris.scaffold.IrisWorlds;
import com.volmit.iris.pregen.DirectWorldWriter;
import com.volmit.iris.scaffold.engine.IrisAccess; import com.volmit.iris.scaffold.engine.IrisAccess;
import com.volmit.iris.scaffold.parallel.MultiBurst; import com.volmit.iris.scaffold.parallel.MultiBurst;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
@ -64,7 +63,6 @@ public class PregenJob implements Listener
private long pausedAt = 0; private long pausedAt = 0;
private double pms = 0; private double pms = 0;
private boolean gleaming = false; private boolean gleaming = false;
private final DirectWorldWriter writer;
int xc = 0; int xc = 0;
private IrisAccess access = null; private IrisAccess access = null;
private static int tid = 0; private static int tid = 0;
@ -94,7 +92,6 @@ public class PregenJob implements Listener
burst = new MultiBurst(gleaming ? IrisSettings.get().getMaxAsyncChunkPregenThreads() : tc()); burst = new MultiBurst(gleaming ? IrisSettings.get().getMaxAsyncChunkPregenThreads() : tc());
instance = this; instance = this;
working = new Semaphore(gleaming ? IrisSettings.get().getMaxAsyncChunkPregenThreads() : tc()); working = new Semaphore(gleaming ? IrisSettings.get().getMaxAsyncChunkPregenThreads() : tc());
writer =IrisSettings.get().isUseExperimentalGleamMCADirectWriteMode() ? new DirectWorldWriter(world.getWorldFolder()) : null;
this.s = PrecisionStopwatch.start(); this.s = PrecisionStopwatch.start();
Iris.instance.registerListener(this); Iris.instance.registerListener(this);
this.world = world; this.world = world;
@ -130,10 +127,6 @@ public class PregenJob implements Listener
mcaX = x; mcaX = x;
mcaZ = z; mcaZ = z;
chunkSpiraler.retarget(cubeSize, cubeSize); chunkSpiraler.retarget(cubeSize, cubeSize);
if(writer != null)
{
writer.flush();
}
ticks++; ticks++;
}); });
@ -173,11 +166,6 @@ public class PregenJob implements Listener
{ {
try try
{ {
if(instance.writer != null)
{
instance.writer.flush();
}
Bukkit.getScheduler().cancelTask(task); Bukkit.getScheduler().cancelTask(task);
if(consumer != null) if(consumer != null)
@ -203,11 +191,6 @@ public class PregenJob implements Listener
instance.pms = instance.s.getMilliseconds(); instance.pms = instance.s.getMilliseconds();
instance.paused = true; instance.paused = true;
instance.pausedAt = M.ms(); instance.pausedAt = M.ms();
if(instance.writer != null)
{
instance.writer.flush();
}
} }
public static void resume() public static void resume()
@ -268,9 +251,7 @@ public class PregenJob implements Listener
{ {
long eta = (long) ((total - genned) * (s.getMilliseconds() / (double) genned)); long eta = (long) ((total - genned) * (s.getMilliseconds() / (double) genned));
String ss = "Pregen: " + Form.pc(Math.min((double) genned / (double) total, 1.0), 0) + ", Elapsed: " + String ss = "Pregen: " + Form.pc(Math.min((double) genned / (double) total, 1.0), 0) + ", Elapsed: " +
Form.duration((long) (paused ? pms : s.getMilliseconds())) Form.duration((long) (paused ? pms : s.getMilliseconds()))
+ ", ETA: " + (genned >= total - 5 ? "Any second..." : s.getMilliseconds() < 25000 ? "Calculating..." : Form.duration(eta)) + " MS: " + Form.duration((s.getMilliseconds() / (double) genned), 2); + ", ETA: " + (genned >= total - 5 ? "Any second..." : s.getMilliseconds() < 25000 ? "Calculating..." : Form.duration(eta)) + " MS: " + Form.duration((s.getMilliseconds() / (double) genned), 2);
Iris.info(ss); Iris.info(ss);
if(sender.isPlayer() && sender.player().isOnline()) if(sender.isPlayer() && sender.player().isOnline())
@ -441,17 +422,7 @@ public class PregenJob implements Listener
} }
int xx = cx; int xx = cx;
int zz = cz; int zz = cz;
if(IrisSettings.get().isUseExperimentalGleamMCADirectWriteMode())
{
access().directWriteChunk(world, cx, cz, writer);
}
else
{
access().generatePaper(world, cx, cz); access().generatePaper(world, cx, cz);
}
working.release(); working.release();
genned++; genned++;
nogen = M.ms(); nogen = M.ms();
@ -637,11 +608,6 @@ Runnable rr = () ->
world.save(); world.save();
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "save-all"); Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "save-all");
} }
if(instance.writer != null)
{
instance.writer.flush();
}
} }
public int max() public int max()