diff options
| author | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2021-06-03 14:03:12 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-06-03 14:03:12 +0200 |
| commit | 1303fe97510fb7987746722b3261c696f523fbd5 (patch) | |
| tree | d927dbd4c71a5ea6435f5994e8fa0bc90ef19b2c /opendc-compute | |
| parent | ae987fa84b2e061eb9fdfec5561e1c976aaa5a54 (diff) | |
| parent | cef12722f03a24a0e1e3b7502fb5e434d93f1664 (diff) | |
simulator: Improve simulator resource model (#142)
This pull request improves the existing simulator resource model
that is at the core of all simulation models in OpenDC.
Most importantly, we have changed the way of how metrics are reported by this layer.
* Add `SimResourceInterpreter` which is responsible for efficiently scheduling
communication between resources in OpenDC. The performance gain is in the 2x-5x range.
* Add uniform interface for exposing resource metrics (using `SimResourceCounters`).
* Split the CPUFreq subsystem in the compute simulator as it mixed responsibilities of
different layers.
**Breaking API Changes**
* Resource providers now accept a `SimResourceInterpreter` which is
responsible for coordinating the communication between resources.
* `ScalingGovernor` is not part of the machine layer anymore. Instead, it should
move in the OS/Hypervisor layer.
* Workloads should now start CPU consumers using `cpu.startConsumer`.
Diffstat (limited to 'opendc-compute')
2 files changed, 28 insertions, 13 deletions
diff --git a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt index 68667a8c..d36717af 100644 --- a/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt +++ b/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt @@ -32,15 +32,16 @@ import org.opendc.compute.api.ServerState import org.opendc.compute.service.driver.* import org.opendc.simulator.compute.* import org.opendc.simulator.compute.cpufreq.PerformanceScalingGovernor -import org.opendc.simulator.compute.cpufreq.ScalingDriver import org.opendc.simulator.compute.cpufreq.ScalingGovernor -import org.opendc.simulator.compute.cpufreq.SimpleScalingDriver import org.opendc.simulator.compute.interference.IMAGE_PERF_INTERFERENCE_MODEL import org.opendc.simulator.compute.interference.PerformanceInterferenceModel import org.opendc.simulator.compute.model.MemoryUnit import org.opendc.simulator.compute.power.ConstantPowerModel +import org.opendc.simulator.compute.power.PowerDriver import org.opendc.simulator.compute.power.PowerModel +import org.opendc.simulator.compute.power.SimplePowerDriver import org.opendc.simulator.failures.FailureDomain +import org.opendc.simulator.resources.SimResourceInterpreter import java.time.Clock import java.util.* import kotlin.coroutines.CoroutineContext @@ -59,7 +60,7 @@ public class SimHost( meter: Meter, hypervisor: SimHypervisorProvider, scalingGovernor: ScalingGovernor, - scalingDriver: ScalingDriver, + scalingDriver: PowerDriver, private val mapper: SimWorkloadMapper = SimMetaWorkloadMapper(), ) : Host, FailureDomain, AutoCloseable { @@ -74,7 +75,7 @@ public class SimHost( hypervisor: SimHypervisorProvider, powerModel: PowerModel = ConstantPowerModel(0.0), mapper: SimWorkloadMapper = SimMetaWorkloadMapper(), - ) : this(uid, name, model, meta, context, clock, meter, hypervisor, PerformanceScalingGovernor(), SimpleScalingDriver(powerModel), mapper) + ) : this(uid, name, model, meta, context, clock, meter, hypervisor, PerformanceScalingGovernor(), SimplePowerDriver(powerModel), mapper) /** * The [CoroutineScope] of the host bounded by the lifecycle of the host. @@ -94,19 +95,24 @@ public class SimHost( /** * Current total memory use of the images on this hypervisor. */ - private var availableMemory: Long = model.memory.map { it.size }.sum() + private var availableMemory: Long = model.memory.sumOf { it.size } + + /** + * The resource interpreter to schedule the resource interactions. + */ + private val interpreter = SimResourceInterpreter(context, clock) /** * The machine to run on. */ - public val machine: SimBareMetalMachine = SimBareMetalMachine(context, clock, model, scalingGovernor, scalingDriver) + public val machine: SimBareMetalMachine = SimBareMetalMachine(interpreter, model, scalingDriver) /** * The hypervisor to run multiple workloads. */ public val hypervisor: SimHypervisor = hypervisor.create( - scope.coroutineContext, clock, - object : SimHypervisor.Listener { + interpreter, + listener = object : SimHypervisor.Listener { override fun onSliceFinish( hypervisor: SimHypervisor, requestedWork: Long, diff --git a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt index 5594fd59..a6cff3ba 100644 --- a/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt +++ b/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt @@ -124,9 +124,18 @@ internal class SimHostTest { object : MetricExporter { override fun export(metrics: Collection<MetricData>): CompletableResultCode { val metricsByName = metrics.associateBy { it.name } - requestedWork += metricsByName.getValue("cpu.work.total").doubleSummaryData.points.first().sum.toLong() - grantedWork += metricsByName.getValue("cpu.work.granted").doubleSummaryData.points.first().sum.toLong() - overcommittedWork += metricsByName.getValue("cpu.work.overcommit").doubleSummaryData.points.first().sum.toLong() + val totalWork = metricsByName["cpu.work.total"] + if (totalWork != null) { + requestedWork += totalWork.doubleSummaryData.points.first().sum.toLong() + } + val grantedWorkCycle = metricsByName["cpu.work.granted"] + if (grantedWorkCycle != null) { + grantedWork += grantedWorkCycle.doubleSummaryData.points.first().sum.toLong() + } + val overcommittedWorkCycle = metricsByName["cpu.work.overcommit"] + if (overcommittedWorkCycle != null) { + overcommittedWork += overcommittedWorkCycle.doubleSummaryData.points.first().sum.toLong() + } return CompletableResultCode.ofSuccess() } @@ -160,8 +169,8 @@ internal class SimHostTest { reader.close() assertAll( - { assertEquals(4197600, requestedWork, "Requested work does not match") }, - { assertEquals(2157600, grantedWork, "Granted work does not match") }, + { assertEquals(4147200, requestedWork, "Requested work does not match") }, + { assertEquals(2107200, grantedWork, "Granted work does not match") }, { assertEquals(2040000, overcommittedWork, "Overcommitted work does not match") }, { assertEquals(1500001, clock.millis()) } ) |
