summaryrefslogtreecommitdiff
path: root/opendc-simulator/opendc-simulator-flow
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2021-10-25 20:57:51 +0200
committerGitHub <noreply@github.com>2021-10-25 20:57:51 +0200
commita8e2d460a3b6803845687585ae0b34e67a9445a3 (patch)
tree6249023f8f0d56392400c7ebb72238ee848f740a /opendc-simulator/opendc-simulator-flow
parentb4bf7268cbb6d22d3966f469a6b7721b04d91907 (diff)
parent86c65e875b7dde8872dc81a37aa9dca72eee7782 (diff)
merge: Improve the OpenDC compute model (#37)
This pull request contains various improvements to the OpenDC compute simulation model. - Support filtering hosts based on CPU capacity - Do not allocate lambda in fast-path - Redesign VM interference algorithm - Report provisioning time of virtual machines - Prevent allocations during collection cycle - Use correct flow input capacity for counters - Support running workloads without coroutines **Breaking API Changes** - `VirtualMachine` now requires `cpuCapacity` parameter. - `VmInterferenceModel` needs to be constructed using `VmInterferenceModel.Builder` and can't be passed a list of groups anymore. - Scheduling latency is not collected anymore. Instead, use the boot time and provisioning time to derive the scheduling latency. - Telemetry data is recorded using `*TableReader` interfaces as opposed to the `*Data` classes. These classes are re-used per row and should not be shared with other threads, since the underlying data may change. - `SimMachine` does not implement `AutoCloseable` anymore. Machines can be removed from a `SimHypervisor` using the `removeMachine` method. - `SimMachine.run` is moved to an extension method called `runWorkload`. Users can now also choose to run a workload using the asynchronous `SimMachine.startWorkload`.
Diffstat (limited to 'opendc-simulator/opendc-simulator-flow')
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/FlowMultiplexer.kt10
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexer.kt2
-rw-r--r--opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt20
3 files changed, 28 insertions, 4 deletions
diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/FlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/FlowMultiplexer.kt
index 04ba7f21..a7877546 100644
--- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/FlowMultiplexer.kt
+++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/FlowMultiplexer.kt
@@ -62,13 +62,21 @@ public interface FlowMultiplexer {
public val counters: FlowCounters
/**
- * Create a new input on this multiplexer.
+ * Create a new input on this multiplexer with a coupled capacity.
*
* @param key The key of the interference member to which the input belongs.
*/
public fun newInput(key: InterferenceKey? = null): FlowConsumer
/**
+ * Create a new input on this multiplexer with the specified [capacity].
+ *
+ * @param capacity The capacity of the input.
+ * @param key The key of the interference member to which the input belongs.
+ */
+ public fun newInput(capacity: Double, key: InterferenceKey? = null): FlowConsumer
+
+ /**
* Remove [input] from this multiplexer.
*/
public fun removeInput(input: FlowConsumer)
diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexer.kt
index 125d10fe..b68a8baa 100644
--- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexer.kt
+++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/ForwardingFlowMultiplexer.kt
@@ -78,6 +78,8 @@ public class ForwardingFlowMultiplexer(private val engine: FlowEngine) : FlowMul
return input
}
+ override fun newInput(capacity: Double, key: InterferenceKey?): FlowConsumer = newInput(key)
+
override fun removeInput(input: FlowConsumer) {
if (!_inputs.remove(input)) {
return
diff --git a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt
index a0fb8a4e..3d26efda 100644
--- a/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt
+++ b/opendc-simulator/opendc-simulator-flow/src/main/kotlin/org/opendc/simulator/flow/mux/MaxMinFlowMultiplexer.kt
@@ -86,7 +86,15 @@ public class MaxMinFlowMultiplexer(
private val scheduler = Scheduler(engine, parent)
override fun newInput(key: InterferenceKey?): FlowConsumer {
- val provider = Input(engine, scheduler, interferenceDomain, key, scheduler.capacity)
+ return newInput(isCoupled = true, Double.POSITIVE_INFINITY, key)
+ }
+
+ override fun newInput(capacity: Double, key: InterferenceKey?): FlowConsumer {
+ return newInput(isCoupled = false, capacity, key)
+ }
+
+ private fun newInput(isCoupled: Boolean, initialCapacity: Double, key: InterferenceKey?): FlowConsumer {
+ val provider = Input(engine, scheduler, interferenceDomain, key, isCoupled, initialCapacity)
_inputs.add(provider)
return provider
}
@@ -206,7 +214,10 @@ public class MaxMinFlowMultiplexer(
// Disable timers and convergence of the source if one of the output manages it
input.shouldConsumerConverge = !hasActivationOutput
input.enableTimers = !hasActivationOutput
- input.capacity = capacity
+
+ if (input.isCoupled) {
+ input.capacity = capacity
+ }
trigger(_clock.millis())
}
@@ -340,7 +351,9 @@ public class MaxMinFlowMultiplexer(
capacity = newCapacity
for (input in _activeInputs) {
- input.capacity = newCapacity
+ if (input.isCoupled) {
+ input.capacity = newCapacity
+ }
}
// Sort outputs by their capacity
@@ -495,6 +508,7 @@ public class MaxMinFlowMultiplexer(
private val scheduler: Scheduler,
private val interferenceDomain: InterferenceDomain?,
@JvmField val key: InterferenceKey?,
+ @JvmField val isCoupled: Boolean,
initialCapacity: Double,
) : FlowConsumer, FlowConsumerLogic, Comparable<Input> {
/**