Merge pull request #482 from VolmitSoftware/performance

Iris MPC
This commit is contained in:
Dan 2021-07-27 17:33:09 -04:00 committed by GitHub
commit 8f7db7e52f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 247 additions and 148 deletions

View File

@ -19,6 +19,7 @@
package com.volmit.iris.engine; package com.volmit.iris.engine;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.engine.framework.*; import com.volmit.iris.engine.framework.*;
import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.hunk.Hunk;
import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisBiome;
@ -26,7 +27,11 @@ import com.volmit.iris.engine.object.IrisBiomePaletteLayer;
import com.volmit.iris.engine.object.IrisDecorator; import com.volmit.iris.engine.object.IrisDecorator;
import com.volmit.iris.engine.object.IrisObjectPlacement; import com.volmit.iris.engine.object.IrisObjectPlacement;
import com.volmit.iris.engine.parallel.BurstExecutor; import com.volmit.iris.engine.parallel.BurstExecutor;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.documentation.ChunkCoordinates; import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.PrecisionStopwatch; import com.volmit.iris.util.scheduling.PrecisionStopwatch;
@ -158,44 +163,63 @@ public class IrisEngine extends BlockPopulator implements Engine {
@ChunkCoordinates @ChunkCoordinates
@Override @Override
public void generate(int x, int z, Hunk<BlockData> vblocks, Hunk<Biome> vbiomes) { public void generate(int x, int z, Hunk<BlockData> vblocks, Hunk<Biome> vbiomes, boolean multicore) {
try { try {
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
Hunk<BlockData> blocks = vblocks.listen((xx, y, zz, t) -> catchBlockUpdates(x + xx, y + getMinHeight(), z + zz, t)); Hunk<BlockData> blocks = vblocks.listen((xx, y, zz, t) -> catchBlockUpdates(x + xx, y + getMinHeight(), z + zz, t));
PrecisionStopwatch px = PrecisionStopwatch.start();
// This is a very weird optimization, but it works if(multicore)
// Basically we precache multicore the biome stream which effectivley {
// makes the biome stream, interpolation & noise engine run in parallel without mca BurstExecutor b = burst().burst(16);
BurstExecutor b = burst().burst(16); for (int i = 0; i < vblocks.getWidth(); i++) {
int finalI = i;
b.queue(() -> {
for (int j = 0; j < vblocks.getDepth(); j++) {
getFramework().getComplex().getTrueBiomeStream().get(x + finalI, z + j);
getFramework().getComplex().getTrueHeightStream().get(x + finalI, z + j);
}
});
}
for (int i = 0; i < vblocks.getWidth(); i++) { b.complete();
int finalI = i;
b.queue(() -> {
for (int j = 0; j < vblocks.getDepth(); j++) {
getFramework().getComplex().getTrueBiomeStream().get(x + finalI, z + j);
}
});
} }
b.complete(); getMetrics().getPrecache().put(px.getMilliseconds());
switch (getDimension().getTerrainMode()) { switch (getDimension().getTerrainMode()) {
case NORMAL -> { case NORMAL -> {
getFramework().getEngineParallax().generateParallaxArea(x >> 4, z >> 4); getFramework().getEngineParallax().generateParallaxArea(x >> 4, z >> 4);
getFramework().getTerrainActuator().actuate(x, z, vblocks); getFramework().getTerrainActuator().actuate(x, z, vblocks, multicore);
getFramework().getBiomeActuator().actuate(x, z, vbiomes); getFramework().getBiomeActuator().actuate(x, z, vbiomes, multicore);
getFramework().getCaveModifier().modify(x, z, vblocks); getFramework().getCaveModifier().modify(x, z, vblocks, multicore);
getFramework().getRavineModifier().modify(x, z, vblocks); getFramework().getRavineModifier().modify(x, z, vblocks, multicore);
getFramework().getPostModifier().modify(x, z, vblocks); getFramework().getPostModifier().modify(x, z, vblocks, multicore);
getFramework().getDecorantActuator().actuate(x, z, blocks); getFramework().getDecorantActuator().actuate(x, z, blocks, multicore);
getFramework().getEngineParallax().insertParallax(x >> 4, z >> 4, blocks); getFramework().getEngineParallax().insertParallax(x >> 4, z >> 4, blocks);
getFramework().getDepositModifier().modify(x, z, blocks); getFramework().getDepositModifier().modify(x, z, blocks, multicore);
} }
case ISLANDS -> { case ISLANDS -> {
getFramework().getTerrainActuator().actuate(x, z, vblocks); getFramework().getTerrainActuator().actuate(x, z, vblocks, multicore);
} }
} }
getMetrics().getTotal().put(p.getMilliseconds()); getMetrics().getTotal().put(p.getMilliseconds());
if(IrisSettings.get().getGeneral().isDebug())
{
KList<String> v = new KList<>();
KMap<String, Double> g = getMetrics().pull();
for(String i : g.sortKNumber())
{
if(g.get(i) != null)
{
v.add(C.RESET + "" + C.LIGHT_PURPLE + i + ": " + C.UNDERLINE + C.BLUE + Form.duration(g.get(i), 0) + C.RESET + C.GRAY + "");
}
}
Iris.debug(v.toString(", "));
}
} catch (Throwable e) { } catch (Throwable e) {
Iris.reportError(e); Iris.reportError(e);
fail("Failed to generate " + x + ", " + z, e); fail("Failed to generate " + x + ", " + z, e);

View File

@ -213,11 +213,11 @@ public class IrisEngineCompound implements EngineCompound {
} }
@Override @Override
public void generate(int x, int z, Hunk<BlockData> blocks, Hunk<BlockData> postblocks, Hunk<Biome> biomes) { public void generate(int x, int z, Hunk<BlockData> blocks, Hunk<BlockData> postblocks, Hunk<Biome> biomes, boolean multicore) {
recycle(); recycle();
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
if (engines.length == 1 && !getEngine(0).getTarget().isInverted()) { if (engines.length == 1 && !getEngine(0).getTarget().isInverted()) {
engines[0].generate(x, z, blocks, biomes); engines[0].generate(x, z, blocks, biomes, multicore);
} else { } else {
int i; int i;
int offset = 0; int offset = 0;
@ -234,7 +234,7 @@ public class IrisEngineCompound implements EngineCompound {
cbiome = cbiome.invertY(); cbiome = cbiome.invertY();
} }
engine.generate(x, z, cblock, cbiome); engine.generate(x, z, cblock, cbiome, multicore);
blocks.insert(0, doffset, 0, cblock); blocks.insert(0, doffset, 0, cblock);
biomes.insert(0, doffset, 0, cbiome); biomes.insert(0, doffset, 0, cbiome);
offset += height; offset += height;

View File

@ -63,7 +63,7 @@ public class IrisBiomeActuator extends EngineAssignedActuator<Biome> {
@BlockCoordinates @BlockCoordinates
@Override @Override
public void onActuate(int x, int z, Hunk<Biome> h) { public void onActuate(int x, int z, Hunk<Biome> h, boolean multicore) {
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
int zf, maxHeight; int zf, maxHeight;
IrisBiome ib; IrisBiome ib;

View File

@ -80,7 +80,7 @@ public class IrisDecorantActuator extends EngineAssignedActuator<BlockData> {
@BlockCoordinates @BlockCoordinates
@Override @Override
public void onActuate(int x, int z, Hunk<BlockData> output) { public void onActuate(int x, int z, Hunk<BlockData> output, boolean multicore) {
if (!getEngine().getDimension().isDecorate()) { if (!getEngine().getDimension().isDecorate()) {
return; return;
} }

View File

@ -53,7 +53,7 @@ public class IrisTerrainIslandActuator extends EngineAssignedActuator<BlockData>
@BlockCoordinates @BlockCoordinates
@Override @Override
public void onActuate(int x, int z, Hunk<BlockData> h) { public void onActuate(int x, int z, Hunk<BlockData> h, boolean multicore) {
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
int i, zf, depth, surface, realX, realZ; int i, zf, depth, surface, realX, realZ;
IrisBiome biome; IrisBiome biome;

View File

@ -22,6 +22,7 @@ import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineAssignedActuator; import com.volmit.iris.engine.framework.EngineAssignedActuator;
import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.hunk.Hunk;
import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisBiome;
import com.volmit.iris.engine.parallel.BurstExecutor;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.documentation.BlockCoordinates;
import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.RNG;
@ -50,77 +51,104 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator<BlockData>
@BlockCoordinates @BlockCoordinates
@Override @Override
public void onActuate(int x, int z, Hunk<BlockData> h) { public void onActuate(int x, int z, Hunk<BlockData> h, boolean multicore) {
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
int i, zf, depth, realX, realZ, hf, he, b, fdepth;
IrisBiome biome;
KList<BlockData> blocks, fblocks;
for (int xf = 0; xf < h.getWidth(); xf++) { if(multicore)
for (zf = 0; zf < h.getDepth(); zf++) { {
realX = (int) modX(xf + x); BurstExecutor e = getEngine().burst().burst(h.getWidth());
realZ = (int) modZ(zf + z); for (int xf = 0; xf < h.getWidth(); xf++) {
b = hasUnder ? (int) Math.round(getDimension().getUndercarriage().get(rng, realX, realZ)) : 0; int finalXf = xf;
he = (int) Math.round(Math.min(h.getHeight(), getComplex().getHeightStream().get(realX, realZ))); e.queue(() -> terrainSliver(x, z, finalXf, h));
hf = Math.round(Math.max(Math.min(h.getHeight(), getDimension().getFluidHeight()), he)); }
biome = getComplex().getTrueBiomeStream().get(realX, realZ);
blocks = null;
fblocks = null;
if (hf < b) { e.complete();
continue; }
}
for (i = hf; i >= b; i--) { else
if (i >= h.getHeight()) { {
continue; for (int xf = 0; xf < h.getWidth(); xf++) {
} terrainSliver(x, z, xf, h);
if (i == b) {
if (getDimension().isBedrock()) {
h.set(xf, i, zf, BEDROCK);
lastBedrock = i;
continue;
}
}
if (carving && getDimension().isCarved(realX, i, realZ, rng, he)) {
continue;
}
if (i > he && i <= hf) {
fdepth = hf - i;
if (fblocks == null) {
fblocks = biome.generateSeaLayers(realX, realZ, rng, hf - he, getData());
}
if (fblocks.hasIndex(fdepth)) {
h.set(xf, i, zf, fblocks.get(fdepth));
continue;
}
h.set(xf, i, zf, getComplex().getFluidStream().get(realX, +realZ));
continue;
}
if (i <= he) {
depth = he - i;
if (blocks == null) {
blocks = biome.generateLayers(realX, realZ, rng, he, he, getData(), getComplex());
}
if (blocks.hasIndex(depth)) {
h.set(xf, i, zf, blocks.get(depth));
continue;
}
h.set(xf, i, zf, getComplex().getRockStream().get(realX, realZ));
}
}
} }
} }
getEngine().getMetrics().getTerrain().put(p.getMilliseconds()); getEngine().getMetrics().getTerrain().put(p.getMilliseconds());
} }
/**
* This is calling 1/16th of a chunk x/z slice. It is a plane from sky to bedrock 1 thick in the x direction.
* @param x the chunk x in blocks
* @param z the chunk z in blocks
* @param xf the current x slice
* @param h the blockdata
*/
@BlockCoordinates
public void terrainSliver(int x, int z, int xf, Hunk<BlockData> h) {
int i, depth, realX, realZ, hf, he, b, fdepth;
IrisBiome biome;
KList<BlockData> blocks, fblocks;
for (int zf = 0; zf < h.getDepth(); zf++) {
realX = (int) modX(xf + x);
realZ = (int) modZ(zf + z);
b = hasUnder ? (int) Math.round(getDimension().getUndercarriage().get(rng, realX, realZ)) : 0;
he = (int) Math.round(Math.min(h.getHeight(), getComplex().getHeightStream().get(realX, realZ)));
hf = Math.round(Math.max(Math.min(h.getHeight(), getDimension().getFluidHeight()), he));
biome = getComplex().getTrueBiomeStream().get(realX, realZ);
blocks = null;
fblocks = null;
if (hf < b) {
continue;
}
for (i = hf; i >= b; i--) {
if (i >= h.getHeight()) {
continue;
}
if (i == b) {
if (getDimension().isBedrock()) {
h.set(xf, i, zf, BEDROCK);
lastBedrock = i;
continue;
}
}
if (carving && getDimension().isCarved(realX, i, realZ, rng, he)) {
continue;
}
if (i > he && i <= hf) {
fdepth = hf - i;
if (fblocks == null) {
fblocks = biome.generateSeaLayers(realX, realZ, rng, hf - he, getData());
}
if (fblocks.hasIndex(fdepth)) {
h.set(xf, i, zf, fblocks.get(fdepth));
continue;
}
h.set(xf, i, zf, getComplex().getFluidStream().get(realX, +realZ));
continue;
}
if (i <= he) {
depth = he - i;
if (blocks == null) {
blocks = biome.generateLayers(realX, realZ, rng, he, he, getData(), getComplex());
}
if (blocks.hasIndex(depth)) {
h.set(xf, i, zf, blocks.get(depth));
continue;
}
h.set(xf, i, zf, getComplex().getRockStream().get(realX, realZ));
}
}
}
}
} }

View File

@ -111,7 +111,7 @@ public class LinkedTerrainChunk implements TerrainChunk {
} }
@Override @Override
public void setBlock(int x, int y, int z, BlockData blockData) { public synchronized void setBlock(int x, int y, int z, BlockData blockData) {
rawChunkData.setBlock(x, y, z, blockData); rawChunkData.setBlock(x, y, z, blockData);
} }
@ -123,37 +123,37 @@ public class LinkedTerrainChunk implements TerrainChunk {
@Deprecated @Deprecated
@Override @Override
public void setBlock(int x, int y, int z, @NotNull Material material) { public synchronized void setBlock(int x, int y, int z, @NotNull Material material) {
rawChunkData.setBlock(x, y, z, material); rawChunkData.setBlock(x, y, z, material);
} }
@Deprecated @Deprecated
@Override @Override
public void setBlock(int x, int y, int z, @NotNull MaterialData material) { public synchronized void setBlock(int x, int y, int z, @NotNull MaterialData material) {
rawChunkData.setBlock(x, y, z, material); rawChunkData.setBlock(x, y, z, material);
} }
@Deprecated @Deprecated
@Override @Override
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull Material material) { public synchronized void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull Material material) {
rawChunkData.setRegion(xMin, yMin, zMin, xMax, yMax, zMax, material); rawChunkData.setRegion(xMin, yMin, zMin, xMax, yMax, zMax, material);
} }
@Deprecated @Deprecated
@Override @Override
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull MaterialData material) { public synchronized void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull MaterialData material) {
rawChunkData.setRegion(xMin, yMin, zMin, xMax, yMax, zMax, material); rawChunkData.setRegion(xMin, yMin, zMin, xMax, yMax, zMax, material);
} }
@Override @Override
public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull BlockData blockData) { public synchronized void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, @NotNull BlockData blockData) {
rawChunkData.setRegion(xMin, yMin, zMin, xMax, yMax, zMax, blockData); rawChunkData.setRegion(xMin, yMin, zMin, xMax, yMax, zMax, blockData);
} }
@NotNull @NotNull
@Deprecated @Deprecated
@Override @Override
public Material getType(int x, int y, int z) { public synchronized Material getType(int x, int y, int z) {
return rawChunkData.getType(x, y, z); return rawChunkData.getType(x, y, z);
} }

View File

@ -81,7 +81,7 @@ public interface Engine extends DataProvider, Fallible, GeneratorAccess, LootPro
double modifyZ(double z); double modifyZ(double z);
void generate(int x, int z, Hunk<BlockData> blocks, Hunk<Biome> biomes); void generate(int x, int z, Hunk<BlockData> blocks, Hunk<Biome> biomes, boolean multicore);
EngineMetrics getMetrics(); EngineMetrics getMetrics();

View File

@ -23,5 +23,5 @@ import com.volmit.iris.util.documentation.BlockCoordinates;
public interface EngineActuator<O> extends EngineComponent { public interface EngineActuator<O> extends EngineComponent {
@BlockCoordinates @BlockCoordinates
void actuate(int x, int z, Hunk<O> output); void actuate(int x, int z, Hunk<O> output, boolean multicore);
} }

View File

@ -26,11 +26,11 @@ public abstract class EngineAssignedActuator<T> extends EngineAssignedComponent
super(engine, name); super(engine, name);
} }
public abstract void onActuate(int x, int z, Hunk<T> output); public abstract void onActuate(int x, int z, Hunk<T> output, boolean multicore);
@BlockCoordinates @BlockCoordinates
@Override @Override
public void actuate(int x, int z, Hunk<T> output) { public void actuate(int x, int z, Hunk<T> output, boolean multicore) {
onActuate(x, z, output); onActuate(x, z, output, multicore);
} }
} }

View File

@ -25,10 +25,10 @@ public abstract class EngineAssignedModifier<T> extends EngineAssignedComponent
super(engine, name); super(engine, name);
} }
public abstract void onModify(int x, int z, Hunk<T> output); public abstract void onModify(int x, int z, Hunk<T> output, boolean multicore);
@Override @Override
public void modify(int x, int z, Hunk<T> output) { public void modify(int x, int z, Hunk<T> output, boolean multicore) {
onModify(x, z, output); onModify(x, z, output, multicore);
} }
} }

View File

@ -457,7 +457,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
PrecisionStopwatch ps = PrecisionStopwatch.start(); PrecisionStopwatch ps = PrecisionStopwatch.start();
TerrainChunk tc = TerrainChunk.create(world, biome); TerrainChunk tc = TerrainChunk.create(world, biome);
IrisWorld ww = (getComposite() == null || getComposite().getWorld() == null) ? IrisWorld.fromWorld(world) : getComposite().getWorld(); IrisWorld ww = (getComposite() == null || getComposite().getWorld() == null) ? IrisWorld.fromWorld(world) : getComposite().getWorld();
generateChunkRawData(ww, x, z, tc).run(); generateChunkRawData(ww, x, z, tc, true).run();
if (!getComposite().getWorld().hasRealWorld()) { if (!getComposite().getWorld().hasRealWorld()) {
getComposite().getWorld().bind(world); getComposite().getWorld().bind(world);
@ -540,7 +540,7 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
.minHeight(w.minHeight()).maxHeight(w.maxHeight()) .minHeight(w.minHeight()).maxHeight(w.maxHeight())
.injector((xx, yy, zz, biomeBase) -> chunk.setBiomeAt(ox + xx, yy, oz + zz, .injector((xx, yy, zz, biomeBase) -> chunk.setBiomeAt(ox + xx, yy, oz + zz,
INMS.get().getTrueBiomeBaseId(biomeBase))) INMS.get().getTrueBiomeBaseId(biomeBase)))
.build()).run(); .build(), false).run();
} catch (Throwable e) { } catch (Throwable e) {
Iris.error("======================================"); Iris.error("======================================");
e.printStackTrace(); e.printStackTrace();
@ -556,12 +556,12 @@ public class EngineCompositeGenerator extends ChunkGenerator implements IrisAcce
} }
} }
public Runnable generateChunkRawData(IrisWorld world, int x, int z, TerrainChunk tc) { public Runnable generateChunkRawData(IrisWorld world, int x, int z, TerrainChunk tc, boolean multicore) {
initialize(world); initialize(world);
Hunk<BlockData> blocks = Hunk.view((ChunkData) tc); Hunk<BlockData> blocks = Hunk.view((ChunkData) tc);
Hunk<Biome> biomes = Hunk.view((BiomeGrid) tc); Hunk<Biome> biomes = Hunk.view((BiomeGrid) tc);
Hunk<BlockData> post = Hunk.newAtomicHunk(biomes.getWidth(), biomes.getHeight(), biomes.getDepth()); Hunk<BlockData> post = Hunk.newAtomicHunk(biomes.getWidth(), biomes.getHeight(), biomes.getDepth());
compound.get().generate(x * 16, z * 16, blocks, post, biomes); compound.get().generate(x * 16, z * 16, blocks, post, biomes, multicore);
return () -> blocks.insertSoftly(0, 0, 0, post, (b) -> b == null || B.isAirOrFluid(b)); return () -> blocks.insertSoftly(0, 0, 0, post, (b) -> b == null || B.isAirOrFluid(b));
} }

View File

@ -41,7 +41,7 @@ import java.util.List;
public interface EngineCompound extends Listener, Hotloadable, DataProvider { public interface EngineCompound extends Listener, Hotloadable, DataProvider {
IrisDimension getRootDimension(); IrisDimension getRootDimension();
void generate(int x, int z, Hunk<BlockData> blocks, Hunk<BlockData> postblocks, Hunk<Biome> biomes); void generate(int x, int z, Hunk<BlockData> blocks, Hunk<BlockData> postblocks, Hunk<Biome> biomes, boolean multicore);
IrisWorld getWorld(); IrisWorld getWorld();

View File

@ -28,6 +28,7 @@ public class EngineMetrics {
private final AtomicRollingSequence updates; private final AtomicRollingSequence updates;
private final AtomicRollingSequence terrain; private final AtomicRollingSequence terrain;
private final AtomicRollingSequence biome; private final AtomicRollingSequence biome;
private final AtomicRollingSequence precache;
private final AtomicRollingSequence parallax; private final AtomicRollingSequence parallax;
private final AtomicRollingSequence parallaxInsert; private final AtomicRollingSequence parallaxInsert;
private final AtomicRollingSequence post; private final AtomicRollingSequence post;
@ -37,6 +38,7 @@ public class EngineMetrics {
private final AtomicRollingSequence deposit; private final AtomicRollingSequence deposit;
public EngineMetrics(int mem) { public EngineMetrics(int mem) {
this.precache = new AtomicRollingSequence(mem);
this.total = new AtomicRollingSequence(mem); this.total = new AtomicRollingSequence(mem);
this.terrain = new AtomicRollingSequence(mem); this.terrain = new AtomicRollingSequence(mem);
this.biome = new AtomicRollingSequence(mem); this.biome = new AtomicRollingSequence(mem);
@ -52,6 +54,8 @@ public class EngineMetrics {
public KMap<String, Double> pull() { public KMap<String, Double> pull() {
KMap<String, Double> v = new KMap<>(); KMap<String, Double> v = new KMap<>();
v.put("total", total.getAverage());
v.put("precache", precache.getAverage());
v.put("terrain", terrain.getAverage()); v.put("terrain", terrain.getAverage());
v.put("biome", biome.getAverage()); v.put("biome", biome.getAverage());
v.put("parallax", parallax.getAverage()); v.put("parallax", parallax.getAverage());

View File

@ -23,5 +23,5 @@ import com.volmit.iris.util.documentation.BlockCoordinates;
public interface EngineModifier<T> extends EngineComponent { public interface EngineModifier<T> extends EngineComponent {
@BlockCoordinates @BlockCoordinates
void modify(int x, int z, Hunk<T> t); void modify(int x, int z, Hunk<T> t, boolean multicore);
} }

View File

@ -18,6 +18,7 @@
package com.volmit.iris.engine.modifier; package com.volmit.iris.engine.modifier;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.data.B; import com.volmit.iris.engine.data.B;
import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineAssignedModifier; import com.volmit.iris.engine.framework.EngineAssignedModifier;
@ -26,6 +27,7 @@ import com.volmit.iris.engine.noise.FastNoiseDouble;
import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisBiome;
import com.volmit.iris.engine.object.IrisCaveLayer; import com.volmit.iris.engine.object.IrisCaveLayer;
import com.volmit.iris.engine.object.common.CaveResult; import com.volmit.iris.engine.object.common.CaveResult;
import com.volmit.iris.engine.parallel.BurstExecutor;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.scheduling.PrecisionStopwatch; import com.volmit.iris.util.scheduling.PrecisionStopwatch;
@ -48,48 +50,67 @@ public class IrisCaveModifier extends EngineAssignedModifier<BlockData> {
} }
@Override @Override
public void onModify(int x, int z, Hunk<BlockData> a) { public void onModify(int x, int z, Hunk<BlockData> a, boolean multicore) {
if (!getDimension().isCaves()) { if (!getDimension().isCaves()) {
return; return;
} }
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
for (int i = 0; i < a.getWidth(); i++) { if(multicore)
for (int j = 0; j < a.getDepth(); j++) { {
KList<CaveResult> caves = genCaves(x + i, z + j, i, j, a); BurstExecutor e = getEngine().burst().burst(a.getWidth());
int he = (int) Math.round(getComplex().getHeightStream().get(x + i, z + j)); for (int i = 0; i < a.getWidth(); i++) {
if (caves != null && caves.isNotEmpty()) { int finalI = i;
IrisBiome cave = getComplex().getCaveBiomeStream().get(x + i, z + j); e.queue(() -> modifySliver(x, z, finalI, a));
}
if (cave == null) { e.complete();
continue; }
}
for (CaveResult cl : caves) { else
if (cl.getFloor() < 0 || cl.getFloor() > getEngine().getHeight() || cl.getCeiling() > getEngine().getHeight() || cl.getCeiling() < 0) { {
continue; for (int i = 0; i < a.getWidth(); i++) {
} modifySliver(x, z, i, a);
KList<BlockData> floor = cave.generateLayers(x + i, z + j, rng, cl.getFloor(), cl.getFloor(), getData(), getComplex());
KList<BlockData> ceiling = cave.generateLayers(x + i + 656, z + j - 656, rng,
he - cl.getCeiling(),
he - cl.getCeiling(), getData(), getComplex());
for (int g = 0; g < floor.size(); g++) {
a.set(i, cl.getFloor() - g, j, floor.get(g));
}
for (int g = ceiling.size() - 1; g > 0; g--) {
a.set(i, cl.getCeiling() + g, j, ceiling.get(g));
}
}
}
} }
} }
getEngine().getMetrics().getCave().put(p.getMilliseconds()); getEngine().getMetrics().getCave().put(p.getMilliseconds());
} }
public void modifySliver(int x, int z, int finalI, Hunk<BlockData> a)
{
for (int j = 0; j < a.getDepth(); j++) {
KList<CaveResult> caves = genCaves(x + finalI, z + j, finalI, j, a);
int he = (int) Math.round(getComplex().getHeightStream().get(x + finalI, z + j));
if (caves != null && caves.isNotEmpty()) {
IrisBiome cave = getComplex().getCaveBiomeStream().get(x + finalI, z + j);
if (cave == null) {
continue;
}
for (CaveResult cl : caves) {
if (cl.getFloor() < 0 || cl.getFloor() > getEngine().getHeight() || cl.getCeiling() > getEngine().getHeight() || cl.getCeiling() < 0) {
continue;
}
KList<BlockData> floor = cave.generateLayers(x + finalI, z + j, rng, cl.getFloor(), cl.getFloor(), getData(), getComplex());
KList<BlockData> ceiling = cave.generateLayers(x + finalI + 656, z + j - 656, rng,
he - cl.getCeiling(),
he - cl.getCeiling(), getData(), getComplex());
for (int g = 0; g < floor.size(); g++) {
a.set(finalI, cl.getFloor() - g, j, floor.get(g));
}
for (int g = ceiling.size() - 1; g > 0; g--) {
a.set(finalI, cl.getCeiling() + g, j, ceiling.get(g));
}
}
}
}
}
public KList<CaveResult> genCaves(double wxx, double wzz, int x, int z, Hunk<BlockData> data) { public KList<CaveResult> genCaves(double wxx, double wzz, int x, int z, Hunk<BlockData> data) {
if (!getDimension().isCaves()) { if (!getDimension().isCaves()) {
return EMPTY; return EMPTY;

View File

@ -40,7 +40,7 @@ public class IrisDepositModifier extends EngineAssignedModifier<BlockData> {
} }
@Override @Override
public void onModify(int x, int z, Hunk<BlockData> output) { public void onModify(int x, int z, Hunk<BlockData> output, boolean multicore) {
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
generateDeposits(rng, output, Math.floorDiv(x, 16), Math.floorDiv(z, 16)); generateDeposits(rng, output, Math.floorDiv(x, 16), Math.floorDiv(z, 16));
getEngine().getMetrics().getDeposit().put(p.getMilliseconds()); getEngine().getMetrics().getDeposit().put(p.getMilliseconds());

View File

@ -25,6 +25,7 @@ import com.volmit.iris.engine.framework.EngineAssignedModifier;
import com.volmit.iris.engine.hunk.Hunk; import com.volmit.iris.engine.hunk.Hunk;
import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisBiome;
import com.volmit.iris.engine.object.common.CaveResult; import com.volmit.iris.engine.object.common.CaveResult;
import com.volmit.iris.engine.parallel.BurstExecutor;
import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.scheduling.PrecisionStopwatch; import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import org.bukkit.Material; import org.bukkit.Material;
@ -33,6 +34,8 @@ import org.bukkit.block.data.Levelled;
import org.bukkit.block.data.Waterlogged; import org.bukkit.block.data.Waterlogged;
import org.bukkit.block.data.type.Slab; import org.bukkit.block.data.type.Slab;
import java.util.concurrent.atomic.AtomicInteger;
public class IrisPostModifier extends EngineAssignedModifier<BlockData> { public class IrisPostModifier extends EngineAssignedModifier<BlockData> {
private static final BlockData AIR = B.get("CAVE_AIR"); private static final BlockData AIR = B.get("CAVE_AIR");
private static final BlockData WATER = B.get("WATER"); private static final BlockData WATER = B.get("WATER");
@ -44,14 +47,33 @@ public class IrisPostModifier extends EngineAssignedModifier<BlockData> {
} }
@Override @Override
public void onModify(int x, int z, Hunk<BlockData> output) { public void onModify(int x, int z, Hunk<BlockData> output, boolean multicore) {
PrecisionStopwatch p = PrecisionStopwatch.start(); PrecisionStopwatch p = PrecisionStopwatch.start();
int i, j; int i;
for (i = 0; i < output.getWidth(); i++) { AtomicInteger j = new AtomicInteger();
for (j = 0; j < output.getDepth(); j++) { if(multicore)
post(i, j, output, i + x, j + z); {
BurstExecutor e = getEngine().burst().burst(output.getWidth());
for (i = 0; i < output.getWidth(); i++) {
int finalI = i;
e.queue(() -> {
for (j.set(0); j.get() < output.getDepth(); j.getAndIncrement()) {
post(finalI, j.get(), output, finalI + x, j.get() + z);
}
});
}
e.complete();
}
else
{
for (i = 0; i < output.getWidth(); i++) {
for (j.set(0); j.get() < output.getDepth(); j.getAndIncrement()) {
post(i, j.get(), output, i + x, j.get() + z);
}
} }
} }
getEngine().getMetrics().getPost().put(p.getMilliseconds()); getEngine().getMetrics().getPost().put(p.getMilliseconds());
} }

View File

@ -46,7 +46,7 @@ public class IrisRavineModifier extends EngineAssignedModifier<BlockData> {
} }
@Override @Override
public void onModify(int x, int z, Hunk<BlockData> output) { public void onModify(int x, int z, Hunk<BlockData> output, boolean multicore) {
if (!getDimension().isRavines()) { if (!getDimension().isRavines()) {
return; return;
} }