diff options
Diffstat (limited to 'opendc-simulator')
10 files changed, 167 insertions, 17 deletions
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/SimAbstractMachine.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/SimAbstractMachine.java index 40c219ed..f684c54d 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/SimAbstractMachine.java +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/SimAbstractMachine.java @@ -131,6 +131,11 @@ public abstract class SimAbstractMachine implements SimMachine { } @Override + public SimWorkload snapshot() { + return workload.snapshot(); + } + + @Override public void reset() { final FlowGraph graph = getMemory().getInput().getGraph(); diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/SimMachineContext.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/SimMachineContext.java index 0f7d4c8b..bce5c0a8 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/SimMachineContext.java +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/SimMachineContext.java @@ -69,6 +69,13 @@ public interface SimMachineContext { List<? extends SimStorageInterface> getStorageInterfaces(); /** + * Create a snapshot of the {@link SimWorkload} running on this machine. + * + * @throws UnsupportedOperationException if the workload does not support snapshotting. + */ + SimWorkload snapshot(); + + /** * Reset all resources of the machine. */ void reset(); diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/kernel/SimHypervisor.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/kernel/SimHypervisor.java index f03a0c20..4ebcba71 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/kernel/SimHypervisor.java +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/kernel/SimHypervisor.java @@ -240,6 +240,11 @@ public final class SimHypervisor implements SimWorkload { } } + @Override + public SimWorkload snapshot() { + throw new UnsupportedOperationException("Unable to snapshot hypervisor"); + } + /** * The context which carries the state when the hypervisor is running on a machine. */ diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimChainWorkload.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimChainWorkload.java index f838328b..7480b3c0 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimChainWorkload.java +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimChainWorkload.java @@ -44,9 +44,20 @@ final class SimChainWorkload implements SimWorkload { * Construct a {@link SimChainWorkload} instance. * * @param workloads The workloads to chain. + * @param activeWorkloadIndex The index of the active workload. */ - SimChainWorkload(SimWorkload... workloads) { + SimChainWorkload(SimWorkload[] workloads, int activeWorkloadIndex) { this.workloads = workloads; + this.activeWorkloadIndex = activeWorkloadIndex; + } + + /** + * Construct a {@link SimChainWorkload} instance. + * + * @param workloads The workloads to chain. + */ + SimChainWorkload(SimWorkload... workloads) { + this(workloads, 0); } @Override @@ -79,6 +90,19 @@ final class SimChainWorkload implements SimWorkload { tryThrow(context.doStop(workloads[activeWorkloadIndex])); } + @Override + public SimChainWorkload snapshot() { + final int activeWorkloadIndex = this.activeWorkloadIndex; + final SimWorkload[] workloads = this.workloads; + final SimWorkload[] newWorkloads = new SimWorkload[workloads.length - activeWorkloadIndex]; + + for (int i = 0; i < newWorkloads.length; i++) { + newWorkloads[i] = workloads[activeWorkloadIndex + i].snapshot(); + } + + return new SimChainWorkload(newWorkloads, 0); + } + /** * A {@link SimMachineContext} that intercepts the shutdown calls. */ @@ -120,6 +144,12 @@ final class SimChainWorkload implements SimWorkload { } @Override + public SimWorkload snapshot() { + final SimWorkload workload = workloads[activeWorkloadIndex]; + return workload.snapshot(); + } + + @Override public void reset() { ctx.reset(); } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimFlopsWorkload.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimFlopsWorkload.java index f3efbebb..839856bb 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimFlopsWorkload.java +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimFlopsWorkload.java @@ -60,6 +60,7 @@ public class SimFlopsWorkload implements SimWorkload, FlowStageLogic { this.flops = flops; this.utilization = utilization; + this.remainingAmount = flops; } @Override @@ -98,8 +99,13 @@ public class SimFlopsWorkload implements SimWorkload, FlowStageLogic { } @Override - public String toString() { - return "SimFlopsWorkload[FLOPs=" + flops + ",utilization=" + utilization + "]"; + public SimFlopsWorkload snapshot() { + final FlowStage stage = this.stage; + if (stage != null) { + stage.sync(); + } + + return new SimFlopsWorkload((long) remainingAmount, utilization); } @Override @@ -138,4 +144,9 @@ public class SimFlopsWorkload implements SimWorkload, FlowStageLogic { return now + duration; } + + @Override + public String toString() { + return "SimFlopsWorkload[FLOPs=" + flops + ",utilization=" + utilization + "]"; + } } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimRuntimeWorkload.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimRuntimeWorkload.java index 194efafd..9c9f4788 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimRuntimeWorkload.java +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimRuntimeWorkload.java @@ -59,6 +59,7 @@ public class SimRuntimeWorkload implements SimWorkload, FlowStageLogic { this.duration = duration; this.utilization = utilization; + this.remainingDuration = duration; } @Override @@ -98,6 +99,16 @@ public class SimRuntimeWorkload implements SimWorkload, FlowStageLogic { } @Override + public SimRuntimeWorkload snapshot() { + final FlowStage stage = this.stage; + if (stage != null) { + stage.sync(); + } + + return new SimRuntimeWorkload(remainingDuration, utilization); + } + + @Override public long onUpdate(FlowStage ctx, long now) { long lastUpdate = this.lastUpdate; this.lastUpdate = now; diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimTrace.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimTrace.java index 12a567ff..1d8667d5 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimTrace.java +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimTrace.java @@ -71,7 +71,7 @@ public final class SimTrace { * @param offset The offset for the timestamps. */ public SimWorkload createWorkload(long offset) { - return new Workload(offset, usageCol, deadlineCol, coresCol, size); + return new Workload(offset, usageCol, deadlineCol, coresCol, size, 0); } /** @@ -211,22 +211,24 @@ public final class SimTrace { private final long[] deadlineCol; private final int[] coresCol; private final int size; + private final int index; - private Workload(long offset, double[] usageCol, long[] deadlineCol, int[] coresCol, int size) { + private Workload(long offset, double[] usageCol, long[] deadlineCol, int[] coresCol, int size, int index) { this.offset = offset; this.usageCol = usageCol; this.deadlineCol = deadlineCol; this.coresCol = coresCol; this.size = size; + this.index = index; } @Override public void onStart(SimMachineContext ctx) { final WorkloadStageLogic logic; if (ctx.getCpus().size() == 1) { - logic = new SingleWorkloadLogic(ctx, offset, usageCol, deadlineCol, size); + logic = new SingleWorkloadLogic(ctx, offset, usageCol, deadlineCol, size, index); } else { - logic = new MultiWorkloadLogic(ctx, offset, usageCol, deadlineCol, coresCol, size); + logic = new MultiWorkloadLogic(ctx, offset, usageCol, deadlineCol, coresCol, size, index); } this.logic = logic; } @@ -240,6 +242,18 @@ public final class SimTrace { logic.getStage().close(); } } + + @Override + public SimWorkload snapshot() { + final WorkloadStageLogic logic = this.logic; + int index = this.index; + + if (logic != null) { + index = logic.getIndex(); + } + + return new Workload(offset, usageCol, deadlineCol, coresCol, size, index); + } } /** @@ -250,6 +264,11 @@ public final class SimTrace { * Return the {@link FlowStage} belonging to this instance. */ FlowStage getStage(); + + /** + * Return the current index of the workload. + */ + int getIndex(); } /** @@ -268,12 +287,13 @@ public final class SimTrace { private final SimMachineContext ctx; private SingleWorkloadLogic( - SimMachineContext ctx, long offset, double[] usageCol, long[] deadlineCol, int size) { + SimMachineContext ctx, long offset, double[] usageCol, long[] deadlineCol, int size, int index) { this.ctx = ctx; this.offset = offset; this.usageCol = usageCol; this.deadlineCol = deadlineCol; this.size = size; + this.index = index; final FlowGraph graph = ctx.getGraph(); final List<? extends SimProcessingUnit> cpus = ctx.getCpus(); @@ -315,6 +335,11 @@ public final class SimTrace { return stage; } + @Override + public int getIndex() { + return index; + } + /** * Helper method to stop the execution of the workload. */ @@ -346,13 +371,20 @@ public final class SimTrace { private final SimMachineContext ctx; private MultiWorkloadLogic( - SimMachineContext ctx, long offset, double[] usageCol, long[] deadlineCol, int[] coresCol, int size) { + SimMachineContext ctx, + long offset, + double[] usageCol, + long[] deadlineCol, + int[] coresCol, + int size, + int index) { this.ctx = ctx; this.offset = offset; this.usageCol = usageCol; this.deadlineCol = deadlineCol; this.coresCol = coresCol; this.size = size; + this.index = index; final FlowGraph graph = ctx.getGraph(); final List<? extends SimProcessingUnit> cpus = ctx.getCpus(); @@ -418,5 +450,10 @@ public final class SimTrace { public FlowStage getStage() { return stage; } + + @Override + public int getIndex() { + return index; + } } } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimWorkload.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimWorkload.java index 7be51265..cad324fb 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimWorkload.java +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/SimWorkload.java @@ -45,4 +45,9 @@ public interface SimWorkload { * @param ctx The execution context in which the machine runs. */ void onStop(SimMachineContext ctx); + + /** + * Create a snapshot of this workload. + */ + SimWorkload snapshot(); } diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt index cde6763c..2acf6ec7 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt @@ -177,6 +177,8 @@ class SimMachineTest { } override fun onStop(ctx: SimMachineContext) {} + + override fun snapshot(): SimWorkload = TODO() }) } @@ -197,6 +199,8 @@ class SimMachineTest { } override fun onStop(ctx: SimMachineContext) {} + + override fun snapshot(): SimWorkload = TODO() }) } @@ -217,6 +221,8 @@ class SimMachineTest { } override fun onStop(ctx: SimMachineContext) {} + + override fun snapshot(): SimWorkload = TODO() }) assertEquals(1000, clock.millis()) @@ -243,6 +249,8 @@ class SimMachineTest { } override fun onStop(ctx: SimMachineContext) {} + + override fun snapshot(): SimWorkload = TODO() }) assertEquals(40, clock.millis()) @@ -266,6 +274,8 @@ class SimMachineTest { } override fun onStop(ctx: SimMachineContext) {} + + override fun snapshot(): SimWorkload = TODO() }) assertEquals(4000, clock.millis()) @@ -289,6 +299,8 @@ class SimMachineTest { } override fun onStop(ctx: SimMachineContext) {} + + override fun snapshot(): SimWorkload = TODO() }) assertEquals(4000, clock.millis()) diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimChainWorkloadTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimChainWorkloadTest.kt index 2210374d..d0b0efaa 100644 --- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimChainWorkloadTest.kt +++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/workload/SimChainWorkloadTest.kt @@ -25,6 +25,8 @@ package org.opendc.simulator.compute.workload import io.mockk.every import io.mockk.mockk import io.mockk.spyk +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -67,8 +69,8 @@ class SimChainWorkloadTest { val workload = SimWorkloads.chain( - SimRuntimeWorkload(1000, 1.0), - SimRuntimeWorkload(1000, 1.0) + SimWorkloads.runtime(1000, 1.0), + SimWorkloads.runtime(1000, 1.0) ) machine.runWorkload(workload) @@ -93,7 +95,7 @@ class SimChainWorkloadTest { val workload = SimWorkloads.chain( workloadA, - SimRuntimeWorkload(1000, 1.0) + SimWorkloads.runtime(1000, 1.0) ) assertThrows<IllegalStateException> { machine.runWorkload(workload) } @@ -117,9 +119,9 @@ class SimChainWorkloadTest { val workload = SimWorkloads.chain( - SimRuntimeWorkload(1000, 1.0), + SimWorkloads.runtime(1000, 1.0), workloadA, - SimRuntimeWorkload(1000, 1.0) + SimWorkloads.runtime(1000, 1.0) ) assertThrows<IllegalStateException> { machine.runWorkload(workload) } @@ -143,7 +145,7 @@ class SimChainWorkloadTest { val workload = SimWorkloads.chain( workloadA, - SimRuntimeWorkload(1000, 1.0) + SimWorkloads.runtime(1000, 1.0) ) assertThrows<IllegalStateException> { machine.runWorkload(workload) } @@ -166,9 +168,9 @@ class SimChainWorkloadTest { val workload = SimWorkloads.chain( - SimRuntimeWorkload(1000, 1.0), + SimWorkloads.runtime(1000, 1.0), workloadA, - SimRuntimeWorkload(1000, 1.0) + SimWorkloads.runtime(1000, 1.0) ) assertThrows<IllegalStateException> { machine.runWorkload(workload) } @@ -255,4 +257,29 @@ class SimChainWorkloadTest { assertEquals(1, exc.cause!!.suppressedExceptions.size) assertEquals(1000, clock.millis()) } + + @Test + fun testSnapshot() = runSimulation { + val engine = FlowEngine.create(coroutineContext, clock) + val graph = engine.newGraph() + + val machine = SimBareMetalMachine.create(graph, machineModel) + val workload = + SimWorkloads.chain( + SimWorkloads.runtime(1000, 1.0), + SimWorkloads.runtime(1000, 1.0) + ) + + val job = launch { machine.runWorkload(workload) } + delay(500L) + val snapshot = workload.snapshot() + + job.join() + + assertEquals(2000, clock.millis()) + + machine.runWorkload(snapshot) + + assertEquals(3500, clock.millis()) + } } |
