summaryrefslogtreecommitdiff
path: root/opendc-simulator/opendc-simulator-compute/src/test
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2021-05-27 16:34:06 +0200
committerFabian Mastenbroek <mail.fabianm@gmail.com>2021-06-01 14:48:24 +0200
commit9e5e830e15b74f040708e98c09ea41cd96d13871 (patch)
tree5c2ac6bb2e9a37cc7da36f31092f24c33fb2e15c /opendc-simulator/opendc-simulator-compute/src/test
parentcd2e3288d28d23556a81bad76dab0aae2e055ac2 (diff)
simulator: Centralize resource logic in SimResourceInterpreter
This change introduces the SimResourceInterpreter which centralizes the logic for scheduling and interpreting the communication between resource consumer and provider. This approach offers better performance due to avoiding invalidating the state of the resource context when not necessary. Benchmarks show in the best case a 5x performance improvement and at worst a 2x improvement.
Diffstat (limited to 'opendc-simulator/opendc-simulator-compute/src/test')
-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
3 files changed, 59 insertions, 24 deletions
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()