summaryrefslogtreecommitdiff
path: root/opendc-simulator/opendc-simulator-compute
diff options
context:
space:
mode:
Diffstat (limited to 'opendc-simulator/opendc-simulator-compute')
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt21
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractHypervisor.kt13
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt67
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt32
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimFairShareHypervisor.kt8
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimFairShareHypervisorProvider.kt8
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimHypervisorProvider.kt5
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisor.kt6
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisorProvider.kt7
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimHypervisorTest.kt41
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt11
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisorTest.kt31
12 files changed, 133 insertions, 117 deletions
diff --git a/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt b/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt
index 15714aca..bc21edc6 100644
--- a/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/jmh/kotlin/org/opendc/simulator/compute/SimMachineBenchmarks.kt
@@ -34,8 +34,7 @@ import org.opendc.simulator.compute.power.ConstantPowerModel
import org.opendc.simulator.compute.workload.SimTraceWorkload
import org.opendc.simulator.core.SimulationCoroutineScope
import org.opendc.simulator.core.runBlockingSimulation
-import org.opendc.simulator.resources.SimResourceScheduler
-import org.opendc.simulator.resources.SimResourceSchedulerTrampoline
+import org.opendc.simulator.resources.SimResourceInterpreter
import org.openjdk.jmh.annotations.*
import java.util.concurrent.TimeUnit
@@ -46,13 +45,13 @@ import java.util.concurrent.TimeUnit
@OptIn(ExperimentalCoroutinesApi::class)
class SimMachineBenchmarks {
private lateinit var scope: SimulationCoroutineScope
- private lateinit var scheduler: SimResourceScheduler
+ private lateinit var interpreter: SimResourceInterpreter
private lateinit var machineModel: SimMachineModel
@Setup
fun setUp() {
scope = SimulationCoroutineScope()
- scheduler = SimResourceSchedulerTrampoline(scope.coroutineContext, scope.clock)
+ interpreter = SimResourceInterpreter(scope.coroutineContext, scope.clock)
val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2)
@@ -85,7 +84,7 @@ class SimMachineBenchmarks {
fun benchmarkBareMetal(state: Workload) {
return scope.runBlockingSimulation {
val machine = SimBareMetalMachine(
- coroutineContext, clock, machineModel, PerformanceScalingGovernor(),
+ interpreter, machineModel, PerformanceScalingGovernor(),
SimpleScalingDriver(ConstantPowerModel(0.0))
)
return@runBlockingSimulation machine.run(SimTraceWorkload(state.trace))
@@ -96,10 +95,10 @@ class SimMachineBenchmarks {
fun benchmarkSpaceSharedHypervisor(state: Workload) {
return scope.runBlockingSimulation {
val machine = SimBareMetalMachine(
- coroutineContext, clock, machineModel, PerformanceScalingGovernor(),
+ interpreter, machineModel, PerformanceScalingGovernor(),
SimpleScalingDriver(ConstantPowerModel(0.0))
)
- val hypervisor = SimSpaceSharedHypervisor()
+ val hypervisor = SimSpaceSharedHypervisor(interpreter)
launch { machine.run(hypervisor) }
@@ -118,10 +117,10 @@ class SimMachineBenchmarks {
fun benchmarkFairShareHypervisorSingle(state: Workload) {
return scope.runBlockingSimulation {
val machine = SimBareMetalMachine(
- coroutineContext, clock, machineModel, PerformanceScalingGovernor(),
+ interpreter, machineModel, PerformanceScalingGovernor(),
SimpleScalingDriver(ConstantPowerModel(0.0))
)
- val hypervisor = SimFairShareHypervisor(scheduler)
+ val hypervisor = SimFairShareHypervisor(interpreter)
launch { machine.run(hypervisor) }
@@ -140,10 +139,10 @@ class SimMachineBenchmarks {
fun benchmarkFairShareHypervisorDouble(state: Workload) {
return scope.runBlockingSimulation {
val machine = SimBareMetalMachine(
- coroutineContext, clock, machineModel, PerformanceScalingGovernor(),
+ interpreter, machineModel, PerformanceScalingGovernor(),
SimpleScalingDriver(ConstantPowerModel(0.0))
)
- val hypervisor = SimFairShareHypervisor(scheduler)
+ val hypervisor = SimFairShareHypervisor(interpreter)
launch { machine.run(hypervisor) }
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractHypervisor.kt
index 713376e7..2df307d3 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractHypervisor.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractHypervisor.kt
@@ -31,12 +31,13 @@ import org.opendc.simulator.compute.model.MemoryUnit
import org.opendc.simulator.compute.model.ProcessingUnit
import org.opendc.simulator.compute.workload.SimWorkload
import org.opendc.simulator.resources.*
+import org.opendc.simulator.resources.SimResourceSwitch
import java.time.Clock
/**
* Abstract implementation of the [SimHypervisor] interface.
*/
-public abstract class SimAbstractHypervisor : SimHypervisor {
+public abstract class SimAbstractHypervisor(private val interpreter: SimResourceInterpreter) : SimHypervisor {
/**
* The machine on which the hypervisor runs.
*/
@@ -122,11 +123,13 @@ public abstract class SimAbstractHypervisor : SimHypervisor {
override val meta: Map<String, Any> = meta
}
- workload.onStart(ctx)
+ interpreter.batch {
+ workload.onStart(ctx)
- for (cpu in cpus) {
- launch {
- cpu.consume(workload.getConsumer(ctx, cpu.model))
+ for (cpu in cpus) {
+ launch {
+ cpu.consume(workload.getConsumer(ctx, cpu.model))
+ }
}
}
}
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt
index e501033a..de2b3eef 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt
@@ -27,15 +27,18 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import org.opendc.simulator.compute.model.MemoryUnit
import org.opendc.simulator.compute.workload.SimWorkload
+import org.opendc.simulator.resources.SimResourceInterpreter
+import org.opendc.simulator.resources.SimResourceSystem
+import org.opendc.simulator.resources.batch
import org.opendc.simulator.resources.consume
-import org.opendc.simulator.resources.consumer.SimSpeedConsumerAdapter
import java.time.Clock
-import kotlin.coroutines.CoroutineContext
/**
* Abstract implementation of the [SimMachine] interface.
+ *
+ * @param interpreter The interpreter to manage the machine's resources.
*/
-public abstract class SimAbstractMachine(private val clock: Clock) : SimMachine {
+public abstract class SimAbstractMachine(protected val interpreter: SimResourceInterpreter) : SimMachine, SimResourceSystem {
private val _usage = MutableStateFlow(0.0)
override val usage: StateFlow<Double>
get() = _usage
@@ -53,11 +56,6 @@ public abstract class SimAbstractMachine(private val clock: Clock) : SimMachine
private var isTerminated = false
/**
- * The [CoroutineContext] to run in.
- */
- protected abstract val context: CoroutineContext
-
- /**
* The resources allocated for this machine.
*/
protected abstract val cpus: List<SimProcessingUnit>
@@ -67,7 +65,7 @@ public abstract class SimAbstractMachine(private val clock: Clock) : SimMachine
*/
private inner class Context(override val meta: Map<String, Any>) : SimMachineContext {
override val clock: Clock
- get() = this@SimAbstractMachine.clock
+ get() = interpreter.clock
override val cpus: List<SimProcessingUnit> = this@SimAbstractMachine.cpus
@@ -77,38 +75,35 @@ public abstract class SimAbstractMachine(private val clock: Clock) : SimMachine
/**
* Run the specified [SimWorkload] on this machine and suspend execution util the workload has finished.
*/
- override suspend fun run(workload: SimWorkload, meta: Map<String, Any>): Unit = withContext(context) {
- require(!isTerminated) { "Machine is terminated" }
+ override suspend fun run(workload: SimWorkload, meta: Map<String, Any>): Unit = coroutineScope {
+ check(!isTerminated) { "Machine is terminated" }
val ctx = Context(meta)
- val totalCapacity = model.cpus.sumOf { it.frequency }
-
- _speed = DoubleArray(model.cpus.size) { 0.0 }
- var totalSpeed = 0.0
// Before the workload starts, initialize the initial power draw
+ _speed = DoubleArray(model.cpus.size) { 0.0 }
updateUsage(0.0)
- workload.onStart(ctx)
+ interpreter.batch {
+ workload.onStart(ctx)
- for (cpu in cpus) {
- val model = cpu.model
- val consumer = workload.getConsumer(ctx, model)
- val adapter = SimSpeedConsumerAdapter(consumer) { newSpeed ->
- val _speed = _speed
- val _usage = _usage
-
- val oldSpeed = _speed[model.id]
- _speed[model.id] = newSpeed
- totalSpeed = totalSpeed - oldSpeed + newSpeed
-
- val newUsage = totalSpeed / totalCapacity
- if (_usage.value != newUsage) {
- updateUsage(totalSpeed / totalCapacity)
- }
+ for (cpu in cpus) {
+ val model = cpu.model
+ val consumer = workload.getConsumer(ctx, model)
+ launch { cpu.consume(consumer) }
}
+ }
+ }
- launch { cpu.consume(adapter) }
+ override fun onConverge(timestamp: Long) {
+ val totalCapacity = model.cpus.sumOf { it.frequency }
+ val cpus = cpus
+ var totalSpeed = 0.0
+ for (cpu in cpus) {
+ _speed[cpu.model.id] = cpu.speed
+ totalSpeed += cpu.speed
}
+
+ updateUsage(totalSpeed / totalCapacity)
}
/**
@@ -119,9 +114,11 @@ public abstract class SimAbstractMachine(private val clock: Clock) : SimMachine
}
override fun close() {
- if (!isTerminated) {
- isTerminated = true
- cpus.forEach(SimProcessingUnit::close)
+ if (isTerminated) {
+ return
}
+
+ isTerminated = true
+ cpus.forEach(SimProcessingUnit::close)
}
}
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt
index 27ebba21..f5218ba9 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt
@@ -27,8 +27,7 @@ import org.opendc.simulator.compute.cpufreq.ScalingDriver
import org.opendc.simulator.compute.cpufreq.ScalingGovernor
import org.opendc.simulator.compute.model.ProcessingUnit
import org.opendc.simulator.resources.*
-import org.opendc.utils.TimerScheduler
-import java.time.Clock
+import org.opendc.simulator.resources.SimResourceInterpreter
import kotlin.coroutines.*
/**
@@ -43,24 +42,11 @@ import kotlin.coroutines.*
*/
@OptIn(ExperimentalCoroutinesApi::class, InternalCoroutinesApi::class)
public class SimBareMetalMachine(
- context: CoroutineContext,
- private val clock: Clock,
+ platform: SimResourceInterpreter,
override val model: SimMachineModel,
scalingGovernor: ScalingGovernor,
scalingDriver: ScalingDriver
-) : SimAbstractMachine(clock) {
- /**
- * The [Job] associated with this machine.
- */
- private val scope = CoroutineScope(context + Job())
-
- override val context: CoroutineContext = scope.coroutineContext
-
- /**
- * The [TimerScheduler] to use for scheduling the interrupts.
- */
- private val scheduler = SimResourceSchedulerTrampoline(this.context, clock)
-
+) : SimAbstractMachine(platform) {
override val cpus: List<SimProcessingUnit> = model.cpus.map { ProcessingUnitImpl(it) }
/**
@@ -75,6 +61,8 @@ public class SimBareMetalMachine(
scalingGovernor.createLogic(this.scalingDriver.createContext(cpu))
}
+ override val parent: SimResourceSystem? = null
+
init {
scalingGovernors.forEach { it.onStart() }
}
@@ -92,12 +80,6 @@ public class SimBareMetalMachine(
powerDraw = scalingDriver.computePower()
}
- override fun close() {
- super.close()
-
- scope.cancel()
- }
-
/**
* The [SimProcessingUnit] of this machine.
*/
@@ -105,7 +87,7 @@ public class SimBareMetalMachine(
/**
* The actual resource supporting the processing unit.
*/
- private val source = SimResourceSource(model.frequency, scheduler)
+ private val source = SimResourceSource(model.frequency, interpreter, this@SimBareMetalMachine)
override val speed: Double
get() = source.speed
@@ -126,7 +108,7 @@ public class SimBareMetalMachine(
}
override fun close() {
- source.interrupt()
+ source.close()
}
}
}
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimFairShareHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimFairShareHypervisor.kt
index 11aec2de..33e7e637 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimFairShareHypervisor.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimFairShareHypervisor.kt
@@ -23,7 +23,9 @@
package org.opendc.simulator.compute
import org.opendc.simulator.compute.workload.SimWorkload
-import org.opendc.simulator.resources.*
+import org.opendc.simulator.resources.SimResourceInterpreter
+import org.opendc.simulator.resources.SimResourceSwitch
+import org.opendc.simulator.resources.SimResourceSwitchMaxMin
/**
* A [SimHypervisor] that distributes the computing requirements of multiple [SimWorkload] on a single
@@ -31,13 +33,13 @@ import org.opendc.simulator.resources.*
*
* @param listener The hypervisor listener to use.
*/
-public class SimFairShareHypervisor(private val scheduler: SimResourceScheduler, private val listener: SimHypervisor.Listener? = null) : SimAbstractHypervisor() {
+public class SimFairShareHypervisor(private val interpreter: SimResourceInterpreter, private val listener: SimHypervisor.Listener? = null) : SimAbstractHypervisor(interpreter) {
override fun canFit(model: SimMachineModel, switch: SimResourceSwitch): Boolean = true
override fun createSwitch(ctx: SimMachineContext): SimResourceSwitch {
return SimResourceSwitchMaxMin(
- scheduler,
+ interpreter, null,
object : SimResourceSwitchMaxMin.Listener {
override fun onSliceFinish(
switch: SimResourceSwitchMaxMin,
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimFairShareHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimFairShareHypervisorProvider.kt
index 2ab3ea09..68858cc1 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimFairShareHypervisorProvider.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimFairShareHypervisorProvider.kt
@@ -22,9 +22,7 @@
package org.opendc.simulator.compute
-import org.opendc.simulator.resources.SimResourceSchedulerTrampoline
-import java.time.Clock
-import kotlin.coroutines.CoroutineContext
+import org.opendc.simulator.resources.SimResourceInterpreter
/**
* A [SimHypervisorProvider] for the [SimFairShareHypervisor] implementation.
@@ -32,7 +30,7 @@ import kotlin.coroutines.CoroutineContext
public class SimFairShareHypervisorProvider : SimHypervisorProvider {
override val id: String = "fair-share"
- override fun create(context: CoroutineContext, clock: Clock, listener: SimHypervisor.Listener?): SimHypervisor {
- return SimFairShareHypervisor(SimResourceSchedulerTrampoline(context, clock), listener)
+ override fun create(interpreter: SimResourceInterpreter, listener: SimHypervisor.Listener?): SimHypervisor {
+ return SimFairShareHypervisor(interpreter, listener)
}
}
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimHypervisorProvider.kt
index b66020f4..d0753084 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimHypervisorProvider.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimHypervisorProvider.kt
@@ -22,8 +22,7 @@
package org.opendc.simulator.compute
-import java.time.Clock
-import kotlin.coroutines.CoroutineContext
+import org.opendc.simulator.resources.SimResourceInterpreter
/**
* A service provider interface for constructing a [SimHypervisor].
@@ -40,5 +39,5 @@ public interface SimHypervisorProvider {
/**
* Create a [SimHypervisor] instance with the specified [listener].
*/
- public fun create(context: CoroutineContext, clock: Clock, listener: SimHypervisor.Listener? = null): SimHypervisor
+ public fun create(interpreter: SimResourceInterpreter, listener: SimHypervisor.Listener? = null): SimHypervisor
}
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisor.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisor.kt
index fd8e546f..afb47872 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisor.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisor.kt
@@ -22,12 +22,14 @@
package org.opendc.simulator.compute
-import org.opendc.simulator.resources.*
+import org.opendc.simulator.resources.SimResourceInterpreter
+import org.opendc.simulator.resources.SimResourceSwitch
+import org.opendc.simulator.resources.SimResourceSwitchExclusive
/**
* A [SimHypervisor] that allocates its sub-resources exclusively for the virtual machine that it hosts.
*/
-public class SimSpaceSharedHypervisor : SimAbstractHypervisor() {
+public class SimSpaceSharedHypervisor(interpreter: SimResourceInterpreter) : SimAbstractHypervisor(interpreter) {
override fun canFit(model: SimMachineModel, switch: SimResourceSwitch): Boolean {
return switch.inputs.size - switch.outputs.size >= model.cpus.size
}
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisorProvider.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisorProvider.kt
index 83b924d7..c017c8ab 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisorProvider.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisorProvider.kt
@@ -22,8 +22,7 @@
package org.opendc.simulator.compute
-import java.time.Clock
-import kotlin.coroutines.CoroutineContext
+import org.opendc.simulator.resources.SimResourceInterpreter
/**
* A [SimHypervisorProvider] for the [SimSpaceSharedHypervisor] implementation.
@@ -31,7 +30,7 @@ import kotlin.coroutines.CoroutineContext
public class SimSpaceSharedHypervisorProvider : SimHypervisorProvider {
override val id: String = "space-shared"
- override fun create(context: CoroutineContext, clock: Clock, listener: SimHypervisor.Listener?): SimHypervisor {
- return SimSpaceSharedHypervisor()
+ override fun create(interpreter: SimResourceInterpreter, listener: SimHypervisor.Listener?): SimHypervisor {
+ return SimSpaceSharedHypervisor(interpreter)
}
}
diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimHypervisorTest.kt
index 8886caa7..c1b5089c 100644
--- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimHypervisorTest.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimHypervisorTest.kt
@@ -31,6 +31,7 @@ import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertAll
+import org.junit.jupiter.api.assertDoesNotThrow
import org.opendc.simulator.compute.cpufreq.PerformanceScalingGovernor
import org.opendc.simulator.compute.cpufreq.SimpleScalingDriver
import org.opendc.simulator.compute.model.MemoryUnit
@@ -39,7 +40,7 @@ import org.opendc.simulator.compute.model.ProcessingUnit
import org.opendc.simulator.compute.power.ConstantPowerModel
import org.opendc.simulator.compute.workload.SimTraceWorkload
import org.opendc.simulator.core.runBlockingSimulation
-import org.opendc.simulator.resources.SimResourceSchedulerTrampoline
+import org.opendc.simulator.resources.SimResourceInterpreter
/**
* Test suite for the [SimHypervisor] class.
@@ -93,8 +94,9 @@ internal class SimHypervisorTest {
),
)
- val machine = SimBareMetalMachine(coroutineContext, clock, model, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0)))
- val hypervisor = SimFairShareHypervisor(SimResourceSchedulerTrampoline(coroutineContext, clock), listener)
+ val platform = SimResourceInterpreter(coroutineContext, clock)
+ val machine = SimBareMetalMachine(platform, model, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0)))
+ val hypervisor = SimFairShareHypervisor(platform, listener)
launch {
machine.run(hypervisor)
@@ -164,11 +166,12 @@ internal class SimHypervisorTest {
)
)
+ val platform = SimResourceInterpreter(coroutineContext, clock)
val machine = SimBareMetalMachine(
- coroutineContext, clock, model, PerformanceScalingGovernor(),
+ platform, model, PerformanceScalingGovernor(),
SimpleScalingDriver(ConstantPowerModel(0.0))
)
- val hypervisor = SimFairShareHypervisor(SimResourceSchedulerTrampoline(coroutineContext, clock), listener)
+ val hypervisor = SimFairShareHypervisor(platform, listener)
launch {
machine.run(hypervisor)
@@ -190,10 +193,34 @@ internal class SimHypervisorTest {
yield()
assertAll(
- { assertEquals(2082000, listener.totalRequestedWork, "Requested Burst does not match") },
- { assertEquals(1062000, listener.totalGrantedWork, "Granted Burst does not match") },
+ { assertEquals(2073600, listener.totalRequestedWork, "Requested Burst does not match") },
+ { assertEquals(1053600, listener.totalGrantedWork, "Granted Burst does not match") },
{ assertEquals(1020000, listener.totalOvercommittedWork, "Overcommissioned Burst does not match") },
{ assertEquals(1200000, clock.millis()) }
)
}
+
+ @Test
+ fun testMultipleCPUs() = runBlockingSimulation {
+ val cpuNode = ProcessingNode("Intel", "Xeon", "amd64", 2)
+ val model = SimMachineModel(
+ cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 3200.0) },
+ memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) }
+ )
+
+ val platform = SimResourceInterpreter(coroutineContext, clock)
+ val machine = SimBareMetalMachine(
+ platform, model, PerformanceScalingGovernor(),
+ SimpleScalingDriver(ConstantPowerModel(0.0))
+ )
+ val hypervisor = SimFairShareHypervisor(platform)
+
+ assertDoesNotThrow {
+ launch {
+ machine.run(hypervisor)
+ }
+ }
+
+ machine.close()
+ }
}
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 205f2eca..7cc3c6dd 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
@@ -37,6 +37,7 @@ import org.opendc.simulator.compute.model.ProcessingUnit
import org.opendc.simulator.compute.power.ConstantPowerModel
import org.opendc.simulator.compute.workload.SimFlopsWorkload
import org.opendc.simulator.core.runBlockingSimulation
+import org.opendc.simulator.resources.SimResourceInterpreter
/**
* Test suite for the [SimBareMetalMachine] class.
@@ -57,7 +58,7 @@ class SimMachineTest {
@Test
fun testFlopsWorkload() = runBlockingSimulation {
- val machine = SimBareMetalMachine(coroutineContext, clock, machineModel, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0)))
+ val machine = SimBareMetalMachine(SimResourceInterpreter(coroutineContext, clock), machineModel, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0)))
try {
machine.run(SimFlopsWorkload(2_000, utilization = 1.0))
@@ -76,7 +77,7 @@ class SimMachineTest {
cpus = List(cpuNode.coreCount * 2) { ProcessingUnit(cpuNode, it % 2, 1000.0) },
memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) }
)
- val machine = SimBareMetalMachine(coroutineContext, clock, machineModel, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0)))
+ val machine = SimBareMetalMachine(SimResourceInterpreter(coroutineContext, clock), machineModel, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0)))
try {
machine.run(SimFlopsWorkload(2_000, utilization = 1.0))
@@ -90,7 +91,7 @@ class SimMachineTest {
@Test
fun testUsage() = runBlockingSimulation {
- val machine = SimBareMetalMachine(coroutineContext, clock, machineModel, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0)))
+ val machine = SimBareMetalMachine(SimResourceInterpreter(coroutineContext, clock), machineModel, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0)))
val res = mutableListOf<Double>()
val job = launch { machine.usage.toList(res) }
@@ -99,7 +100,7 @@ class SimMachineTest {
machine.run(SimFlopsWorkload(2_000, utilization = 1.0))
yield()
job.cancel()
- assertEquals(listOf(0.0, 0.5, 1.0, 0.5, 0.0), res) { "Machine is fully utilized" }
+ assertEquals(listOf(0.0, 1.0, 0.0), res) { "Machine is fully utilized" }
} finally {
machine.close()
}
@@ -107,7 +108,7 @@ class SimMachineTest {
@Test
fun testClose() = runBlockingSimulation {
- val machine = SimBareMetalMachine(coroutineContext, clock, machineModel, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0)))
+ val machine = SimBareMetalMachine(SimResourceInterpreter(coroutineContext, clock), machineModel, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0)))
machine.close()
assertDoesNotThrow { machine.close() }
diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisorTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisorTest.kt
index ef6f536d..dd824557 100644
--- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisorTest.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimSpaceSharedHypervisorTest.kt
@@ -40,6 +40,7 @@ import org.opendc.simulator.compute.workload.SimFlopsWorkload
import org.opendc.simulator.compute.workload.SimRuntimeWorkload
import org.opendc.simulator.compute.workload.SimTraceWorkload
import org.opendc.simulator.core.runBlockingSimulation
+import org.opendc.simulator.resources.SimResourceInterpreter
/**
* A test suite for the [SimSpaceSharedHypervisor].
@@ -76,11 +77,12 @@ internal class SimSpaceSharedHypervisorTest {
),
)
+ val interpreter = SimResourceInterpreter(coroutineContext, clock)
val machine = SimBareMetalMachine(
- coroutineContext, clock, machineModel, PerformanceScalingGovernor(),
+ SimResourceInterpreter(coroutineContext, clock), machineModel, PerformanceScalingGovernor(),
SimpleScalingDriver(ConstantPowerModel(0.0))
)
- val hypervisor = SimSpaceSharedHypervisor()
+ val hypervisor = SimSpaceSharedHypervisor(interpreter)
val colA = launch { machine.usage.toList(usagePm) }
launch { machine.run(hypervisor) }
@@ -112,11 +114,12 @@ internal class SimSpaceSharedHypervisorTest {
fun testRuntimeWorkload() = runBlockingSimulation {
val duration = 5 * 60L * 1000
val workload = SimRuntimeWorkload(duration)
+ val interpreter = SimResourceInterpreter(coroutineContext, clock)
val machine = SimBareMetalMachine(
- coroutineContext, clock, machineModel, PerformanceScalingGovernor(),
+ interpreter, machineModel, PerformanceScalingGovernor(),
SimpleScalingDriver(ConstantPowerModel(0.0))
)
- val hypervisor = SimSpaceSharedHypervisor()
+ val hypervisor = SimSpaceSharedHypervisor(interpreter)
launch { machine.run(hypervisor) }
yield()
@@ -135,11 +138,12 @@ internal class SimSpaceSharedHypervisorTest {
fun testFlopsWorkload() = runBlockingSimulation {
val duration = 5 * 60L * 1000
val workload = SimFlopsWorkload((duration * 3.2).toLong(), 1.0)
+ val interpreter = SimResourceInterpreter(coroutineContext, clock)
val machine = SimBareMetalMachine(
- coroutineContext, clock, machineModel, PerformanceScalingGovernor(),
+ interpreter, machineModel, PerformanceScalingGovernor(),
SimpleScalingDriver(ConstantPowerModel(0.0))
)
- val hypervisor = SimSpaceSharedHypervisor()
+ val hypervisor = SimSpaceSharedHypervisor(interpreter)
launch { machine.run(hypervisor) }
yield()
@@ -156,11 +160,12 @@ internal class SimSpaceSharedHypervisorTest {
@Test
fun testTwoWorkloads() = runBlockingSimulation {
val duration = 5 * 60L * 1000
+ val interpreter = SimResourceInterpreter(coroutineContext, clock)
val machine = SimBareMetalMachine(
- coroutineContext, clock, machineModel, PerformanceScalingGovernor(),
+ interpreter, machineModel, PerformanceScalingGovernor(),
SimpleScalingDriver(ConstantPowerModel(0.0))
)
- val hypervisor = SimSpaceSharedHypervisor()
+ val hypervisor = SimSpaceSharedHypervisor(interpreter)
launch { machine.run(hypervisor) }
yield()
@@ -182,11 +187,12 @@ internal class SimSpaceSharedHypervisorTest {
*/
@Test
fun testConcurrentWorkloadFails() = runBlockingSimulation {
+ val interpreter = SimResourceInterpreter(coroutineContext, clock)
val machine = SimBareMetalMachine(
- coroutineContext, clock, machineModel, PerformanceScalingGovernor(),
+ interpreter, machineModel, PerformanceScalingGovernor(),
SimpleScalingDriver(ConstantPowerModel(0.0))
)
- val hypervisor = SimSpaceSharedHypervisor()
+ val hypervisor = SimSpaceSharedHypervisor(interpreter)
launch { machine.run(hypervisor) }
yield()
@@ -206,11 +212,12 @@ internal class SimSpaceSharedHypervisorTest {
*/
@Test
fun testConcurrentWorkloadSucceeds() = runBlockingSimulation {
+ val interpreter = SimResourceInterpreter(coroutineContext, clock)
val machine = SimBareMetalMachine(
- coroutineContext, clock, machineModel, PerformanceScalingGovernor(),
+ interpreter, machineModel, PerformanceScalingGovernor(),
SimpleScalingDriver(ConstantPowerModel(0.0))
)
- val hypervisor = SimSpaceSharedHypervisor()
+ val hypervisor = SimSpaceSharedHypervisor(interpreter)
launch { machine.run(hypervisor) }
yield()