summaryrefslogtreecommitdiff
path: root/simulator
diff options
context:
space:
mode:
Diffstat (limited to 'simulator')
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt8
-rw-r--r--simulator/opendc-runner-web/src/main/kotlin/org/opendc/runner/web/Main.kt6
-rw-r--r--simulator/opendc-runner-web/src/main/kotlin/org/opendc/runner/web/WebExperimentMonitor.kt2
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractHypervisor.kt46
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt32
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt39
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineContext.kt10
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimProcessingUnit.kt41
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/DemandScalingGovernor.kt2
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/PStateScalingDriver.kt14
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/PerformanceScalingGovernor.kt2
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ScalingContext.kt10
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ScalingDriver.kt7
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/SimpleScalingDriver.kt9
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt20
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/DemandScalingGovernorTest.kt2
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/PStateScalingDriverTest.kt34
17 files changed, 182 insertions, 102 deletions
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt
index ea775efc..6d87e444 100644
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt
@@ -296,7 +296,6 @@ public class SimHost(
override fun close() {
scope.cancel()
machine.close()
- _state = HostState.DOWN
}
override fun toString(): String = "SimHost[uid=$uid,name=$name,model=$model]"
@@ -389,7 +388,7 @@ public class SimHost(
assert(job == null) { "Concurrent job running" }
val workload = mapper.createWorkload(server)
- val job = scope.launch {
+ job = scope.launch {
delay(1) // TODO Introduce boot time
init()
cont.resume(Unit)
@@ -400,12 +399,9 @@ public class SimHost(
exit(cause)
} finally {
machine.close()
+ job = null
}
}
- this.job = job
- job.invokeOnCompletion {
- this.job = null
- }
}
private fun init() {
diff --git a/simulator/opendc-runner-web/src/main/kotlin/org/opendc/runner/web/Main.kt b/simulator/opendc-runner-web/src/main/kotlin/org/opendc/runner/web/Main.kt
index 90918f44..a368dfee 100644
--- a/simulator/opendc-runner-web/src/main/kotlin/org/opendc/runner/web/Main.kt
+++ b/simulator/opendc-runner-web/src/main/kotlin/org/opendc/runner/web/Main.kt
@@ -234,7 +234,7 @@ public class RunnerCli : CliktCommand(name = "runner") {
)
"mem-inv" -> FilterScheduler(
filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()),
- weighers = listOf(MemoryWeigher() to -1.0)
+ weighers = listOf(MemoryWeigher() to 1.0)
)
"core-mem" -> FilterScheduler(
filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()),
@@ -242,7 +242,7 @@ public class RunnerCli : CliktCommand(name = "runner") {
)
"core-mem-inv" -> FilterScheduler(
filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()),
- weighers = listOf(CoreMemoryWeigher() to -1.0)
+ weighers = listOf(CoreMemoryWeigher() to 1.0)
)
"active-servers" -> FilterScheduler(
filters = listOf(ComputeFilter(), ComputeCapabilitiesFilter()),
@@ -276,7 +276,7 @@ public class RunnerCli : CliktCommand(name = "runner") {
)
val topologyId = scenario.getEmbedded(listOf("topology", "topologyId"), ObjectId::class.java)
val environment = TopologyParser(topologies, topologyId)
- val failureFrequency = operational.get("failureFrequency", Number::class.java)?.toDouble() ?: 24.0 * 7
+ val failureFrequency = if (operational.getBoolean("failuresEnabled", false)) 24.0 * 7 else 0.0
withComputeService(clock, meterProvider, environment, allocationPolicy) { scheduler ->
val failureDomain = if (failureFrequency > 0) {
diff --git a/simulator/opendc-runner-web/src/main/kotlin/org/opendc/runner/web/WebExperimentMonitor.kt b/simulator/opendc-runner-web/src/main/kotlin/org/opendc/runner/web/WebExperimentMonitor.kt
index 8f39b8ac..c913f82f 100644
--- a/simulator/opendc-runner-web/src/main/kotlin/org/opendc/runner/web/WebExperimentMonitor.kt
+++ b/simulator/opendc-runner-web/src/main/kotlin/org/opendc/runner/web/WebExperimentMonitor.kt
@@ -84,7 +84,7 @@ public class WebExperimentMonitor : ExperimentMonitor {
hostAggregateMetrics.totalGrantedBurst + event.grantedBurst,
hostAggregateMetrics.totalOvercommittedBurst + event.overcommissionedBurst,
hostAggregateMetrics.totalInterferedBurst + event.interferedBurst,
- hostAggregateMetrics.totalPowerDraw + (slices * (event.powerDraw / 12)),
+ hostAggregateMetrics.totalPowerDraw + (event.duration * event.powerDraw) / 3600,
hostAggregateMetrics.totalFailureSlices + if (event.host.state != HostState.UP) slices else 0,
hostAggregateMetrics.totalFailureVmSlices + if (event.host.state != HostState.UP) event.vmCount * slices else 0
)
diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractHypervisor.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractHypervisor.kt
index 8046dd53..713376e7 100644
--- a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractHypervisor.kt
+++ b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractHypervisor.kt
@@ -101,7 +101,7 @@ public abstract class SimAbstractHypervisor : SimHypervisor {
/**
* The vCPUs of the machine.
*/
- private val cpus: Map<ProcessingUnit, SimResourceProvider> = model.cpus.associateWith { switch.addOutput(it.frequency) }
+ private val cpus = model.cpus.map { ProcessingUnitImpl(it, switch) }
/**
* Run the specified [SimWorkload] on this machine and suspend execution util the workload has finished.
@@ -111,8 +111,7 @@ public abstract class SimAbstractHypervisor : SimHypervisor {
require(!isTerminated) { "Machine is terminated" }
val ctx = object : SimMachineContext {
- override val cpus: List<ProcessingUnit>
- get() = model.cpus
+ override val cpus: List<SimProcessingUnit> = this@VirtualMachine.cpus
override val memory: List<MemoryUnit>
get() = model.memory
@@ -121,17 +120,13 @@ public abstract class SimAbstractHypervisor : SimHypervisor {
get() = this@SimAbstractHypervisor.context.clock
override val meta: Map<String, Any> = meta
-
- override fun interrupt(cpu: ProcessingUnit) {
- requireNotNull(this@VirtualMachine.cpus[cpu]).interrupt()
- }
}
workload.onStart(ctx)
- for ((cpu, provider) in cpus) {
+ for (cpu in cpus) {
launch {
- provider.consume(workload.getConsumer(ctx, cpu))
+ cpu.consume(workload.getConsumer(ctx, cpu.model))
}
}
}
@@ -144,7 +139,7 @@ public abstract class SimAbstractHypervisor : SimHypervisor {
if (!isTerminated) {
isTerminated = true
- cpus.forEach { (_, provider) -> provider.close() }
+ cpus.forEach(SimProcessingUnit::close)
_vms.remove(this)
}
}
@@ -160,4 +155,35 @@ public abstract class SimAbstractHypervisor : SimHypervisor {
switch.addInput(forwarder)
return forwarder
}
+
+ /**
+ * The [SimProcessingUnit] of this machine.
+ */
+ public inner class ProcessingUnitImpl(override val model: ProcessingUnit, switch: SimResourceSwitch) : SimProcessingUnit {
+ /**
+ * The actual resource supporting the processing unit.
+ */
+ private val source = switch.addOutput(model.frequency)
+
+ override val speed: Double = 0.0 /* TODO Implement */
+
+ override val state: SimResourceState
+ get() = source.state
+
+ override fun startConsumer(consumer: SimResourceConsumer) {
+ source.startConsumer(consumer)
+ }
+
+ override fun interrupt() {
+ source.interrupt()
+ }
+
+ override fun cancel() {
+ source.cancel()
+ }
+
+ override fun close() {
+ source.close()
+ }
+ }
}
diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt
index 252a40ec..0244c5c1 100644
--- a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt
+++ b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt
@@ -26,10 +26,7 @@ import kotlinx.coroutines.*
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
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.SimResourceProvider
-import org.opendc.simulator.resources.SimResourceSource
import org.opendc.simulator.resources.consume
import org.opendc.simulator.resources.consumer.SimSpeedConsumerAdapter
import java.time.Clock
@@ -63,34 +60,26 @@ public abstract class SimAbstractMachine(private val clock: Clock) : SimMachine
/**
* The resources allocated for this machine.
*/
- protected abstract val resources: Map<ProcessingUnit, SimResourceSource>
+ protected abstract val cpus: List<SimProcessingUnit>
/**
* The execution context in which the workload runs.
*/
- private inner class Context(
- val sources: Map<ProcessingUnit, SimResourceProvider>,
- override val meta: Map<String, Any>
- ) : SimMachineContext {
+ private inner class Context(override val meta: Map<String, Any>) : SimMachineContext {
override val clock: Clock
get() = this@SimAbstractMachine.clock
- override val cpus: List<ProcessingUnit> = model.cpus
+ override val cpus: List<SimProcessingUnit> = this@SimAbstractMachine.cpus
override val memory: List<MemoryUnit> = model.memory
-
- override fun interrupt(cpu: ProcessingUnit) {
- checkNotNull(sources[cpu]) { "Invalid resource" }.interrupt()
- }
}
/**
* 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) {
- val resources = resources
require(!isTerminated) { "Machine is terminated" }
- val ctx = Context(resources, meta)
+ val ctx = Context(meta)
val totalCapacity = model.cpus.sumByDouble { it.frequency }
_speed = DoubleArray(model.cpus.size) { 0.0 }
@@ -98,14 +87,15 @@ public abstract class SimAbstractMachine(private val clock: Clock) : SimMachine
workload.onStart(ctx)
- for ((cpu, source) in resources) {
- val consumer = workload.getConsumer(ctx, cpu)
+ 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[cpu.id]
- _speed[cpu.id] = newSpeed
+ val oldSpeed = _speed[model.id]
+ _speed[model.id] = newSpeed
totalSpeed = totalSpeed - oldSpeed + newSpeed
val newUsage = totalSpeed / totalCapacity
@@ -114,7 +104,7 @@ public abstract class SimAbstractMachine(private val clock: Clock) : SimMachine
}
}
- launch { source.consume(adapter) }
+ launch { cpu.consume(adapter) }
}
}
@@ -128,7 +118,7 @@ public abstract class SimAbstractMachine(private val clock: Clock) : SimMachine
override fun close() {
if (!isTerminated) {
isTerminated = true
- resources.forEach { (_, provider) -> provider.close() }
+ cpus.forEach(SimProcessingUnit::close)
}
}
}
diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt
index d5577279..09ee601e 100644
--- a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt
+++ b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimBareMetalMachine.kt
@@ -62,8 +62,7 @@ public class SimBareMetalMachine(
*/
private val scheduler = TimerScheduler<Any>(this.context, clock)
- override val resources: Map<ProcessingUnit, SimResourceSource> =
- model.cpus.associateWith { SimResourceSource(it.frequency, clock, scheduler) }
+ override val cpus: List<SimProcessingUnit> = model.cpus.map { ProcessingUnitImpl(it) }
/**
* Construct the [ScalingDriver.Logic] for this machine.
@@ -73,8 +72,8 @@ public class SimBareMetalMachine(
/**
* The scaling contexts associated with each CPU.
*/
- private val scalingGovernors = resources.map { (cpu, resource) ->
- scalingGovernor.createLogic(this.scalingDriver.createContext(cpu, resource))
+ private val scalingGovernors = cpus.map { cpu ->
+ scalingGovernor.createLogic(this.scalingDriver.createContext(cpu))
}
init {
@@ -100,4 +99,36 @@ public class SimBareMetalMachine(
scheduler.close()
scope.cancel()
}
+
+ /**
+ * The [SimProcessingUnit] of this machine.
+ */
+ public inner class ProcessingUnitImpl(override val model: ProcessingUnit) : SimProcessingUnit {
+ /**
+ * The actual resource supporting the processing unit.
+ */
+ private val source = SimResourceSource(model.frequency, clock, scheduler)
+
+ override val speed: Double
+ get() = source.speed
+
+ override val state: SimResourceState
+ get() = source.state
+
+ override fun startConsumer(consumer: SimResourceConsumer) {
+ source.startConsumer(consumer)
+ }
+
+ override fun interrupt() {
+ source.interrupt()
+ }
+
+ override fun cancel() {
+ source.cancel()
+ }
+
+ override fun close() {
+ source.interrupt()
+ }
+ }
}
diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineContext.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineContext.kt
index 85404e6e..c2523a2a 100644
--- a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineContext.kt
+++ b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineContext.kt
@@ -23,7 +23,6 @@
package org.opendc.simulator.compute
import org.opendc.simulator.compute.model.MemoryUnit
-import org.opendc.simulator.compute.model.ProcessingUnit
import java.time.Clock
/**
@@ -45,17 +44,10 @@ public interface SimMachineContext {
/**
* The CPUs available on the machine.
*/
- public val cpus: List<ProcessingUnit>
+ public val cpus: List<SimProcessingUnit>
/**
* The memory available on the machine
*/
public val memory: List<MemoryUnit>
-
- /**
- * Interrupt the specified [cpu].
- *
- * @throws IllegalArgumentException if the resource does not belong to this execution context.
- */
- public fun interrupt(cpu: ProcessingUnit)
}
diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimProcessingUnit.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimProcessingUnit.kt
new file mode 100644
index 00000000..13c7d9b2
--- /dev/null
+++ b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimProcessingUnit.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2021 AtLarge Research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package org.opendc.simulator.compute
+
+import org.opendc.simulator.compute.model.ProcessingUnit
+import org.opendc.simulator.resources.SimResourceProvider
+
+/**
+ * A simulated processing unit.
+ */
+public interface SimProcessingUnit : SimResourceProvider {
+ /**
+ * The model representing the static properties of the processing unit.
+ */
+ public val model: ProcessingUnit
+
+ /**
+ * The current speed of the processing unit.
+ */
+ public val speed: Double
+}
diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/DemandScalingGovernor.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/DemandScalingGovernor.kt
index 4d62c383..ddbe1ca0 100644
--- a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/DemandScalingGovernor.kt
+++ b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/DemandScalingGovernor.kt
@@ -28,7 +28,7 @@ package org.opendc.simulator.compute.cpufreq
public class DemandScalingGovernor : ScalingGovernor {
override fun createLogic(ctx: ScalingContext): ScalingGovernor.Logic = object : ScalingGovernor.Logic {
override fun onLimit() {
- ctx.setTarget(ctx.resource.speed)
+ ctx.setTarget(ctx.cpu.speed)
}
override fun toString(): String = "DemandScalingGovernor.Logic"
diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/PStateScalingDriver.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/PStateScalingDriver.kt
index 1c82253c..6f44d778 100644
--- a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/PStateScalingDriver.kt
+++ b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/PStateScalingDriver.kt
@@ -23,9 +23,8 @@
package org.opendc.simulator.compute.cpufreq
import org.opendc.simulator.compute.SimMachine
-import org.opendc.simulator.compute.model.ProcessingUnit
+import org.opendc.simulator.compute.SimProcessingUnit
import org.opendc.simulator.compute.power.PowerModel
-import org.opendc.simulator.resources.SimResourceSource
import java.util.*
import kotlin.math.max
import kotlin.math.min
@@ -47,8 +46,8 @@ public class PStateScalingDriver(states: Map<Double, PowerModel>) : ScalingDrive
*/
private val contexts = mutableListOf<ScalingContextImpl>()
- override fun createContext(cpu: ProcessingUnit, resource: SimResourceSource): ScalingContext {
- val ctx = ScalingContextImpl(machine, cpu, resource)
+ override fun createContext(cpu: SimProcessingUnit): ScalingContext {
+ val ctx = ScalingContextImpl(machine, cpu)
contexts.add(ctx)
return ctx
}
@@ -59,7 +58,7 @@ public class PStateScalingDriver(states: Map<Double, PowerModel>) : ScalingDrive
for (ctx in contexts) {
targetFreq = max(ctx.target, targetFreq)
- totalSpeed += ctx.resource.speed
+ totalSpeed += ctx.cpu.speed
}
val maxFreq = states.lastKey()
@@ -73,10 +72,9 @@ public class PStateScalingDriver(states: Map<Double, PowerModel>) : ScalingDrive
private class ScalingContextImpl(
override val machine: SimMachine,
- override val cpu: ProcessingUnit,
- override val resource: SimResourceSource
+ override val cpu: SimProcessingUnit
) : ScalingContext {
- var target = cpu.frequency
+ var target = cpu.model.frequency
private set
override fun setTarget(freq: Double) {
diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/PerformanceScalingGovernor.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/PerformanceScalingGovernor.kt
index c574d5d1..96f8775a 100644
--- a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/PerformanceScalingGovernor.kt
+++ b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/PerformanceScalingGovernor.kt
@@ -28,7 +28,7 @@ package org.opendc.simulator.compute.cpufreq
public class PerformanceScalingGovernor : ScalingGovernor {
override fun createLogic(ctx: ScalingContext): ScalingGovernor.Logic = object : ScalingGovernor.Logic {
override fun onLimit() {
- ctx.setTarget(ctx.resource.capacity)
+ ctx.setTarget(ctx.cpu.model.frequency)
}
override fun toString(): String = "PerformanceScalingGovernor.Logic"
diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ScalingContext.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ScalingContext.kt
index 44cd0168..18338079 100644
--- a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ScalingContext.kt
+++ b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ScalingContext.kt
@@ -23,8 +23,7 @@
package org.opendc.simulator.compute.cpufreq
import org.opendc.simulator.compute.SimMachine
-import org.opendc.simulator.compute.model.ProcessingUnit
-import org.opendc.simulator.resources.SimResourceSource
+import org.opendc.simulator.compute.SimProcessingUnit
/**
* A [ScalingContext] is used to communicate frequency scaling changes between the [ScalingGovernor] and driver.
@@ -38,12 +37,7 @@ public interface ScalingContext {
/**
* The processing unit associated with this context.
*/
- public val cpu: ProcessingUnit
-
- /**
- * The resource associated with this context.
- */
- public val resource: SimResourceSource
+ public val cpu: SimProcessingUnit
/**
* Target the processor to run at the specified target [frequency][freq].
diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ScalingDriver.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ScalingDriver.kt
index 2414eabb..b4fd7550 100644
--- a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ScalingDriver.kt
+++ b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ScalingDriver.kt
@@ -23,8 +23,7 @@
package org.opendc.simulator.compute.cpufreq
import org.opendc.simulator.compute.SimMachine
-import org.opendc.simulator.compute.model.ProcessingUnit
-import org.opendc.simulator.resources.SimResourceSource
+import org.opendc.simulator.compute.SimProcessingUnit
/**
* A [ScalingDriver] is responsible for switching the processor to the correct frequency.
@@ -40,9 +39,9 @@ public interface ScalingDriver {
*/
public interface Logic {
/**
- * Create the [ScalingContext] for the specified [cpu] and [resource] instance.
+ * Create the [ScalingContext] for the specified [cpu] instance.
*/
- public fun createContext(cpu: ProcessingUnit, resource: SimResourceSource): ScalingContext
+ public fun createContext(cpu: SimProcessingUnit): ScalingContext
/**
* Compute the power consumption of the processor.
diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/SimpleScalingDriver.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/SimpleScalingDriver.kt
index b4b564ce..cf0bbb28 100644
--- a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/SimpleScalingDriver.kt
+++ b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/SimpleScalingDriver.kt
@@ -23,9 +23,8 @@
package org.opendc.simulator.compute.cpufreq
import org.opendc.simulator.compute.SimMachine
-import org.opendc.simulator.compute.model.ProcessingUnit
+import org.opendc.simulator.compute.SimProcessingUnit
import org.opendc.simulator.compute.power.PowerModel
-import org.opendc.simulator.resources.SimResourceSource
/**
* A [ScalingDriver] that ignores the instructions of the [ScalingGovernor] and directly computes the power consumption
@@ -33,13 +32,11 @@ import org.opendc.simulator.resources.SimResourceSource
*/
public class SimpleScalingDriver(private val model: PowerModel) : ScalingDriver {
override fun createLogic(machine: SimMachine): ScalingDriver.Logic = object : ScalingDriver.Logic {
- override fun createContext(cpu: ProcessingUnit, resource: SimResourceSource): ScalingContext {
+ override fun createContext(cpu: SimProcessingUnit): ScalingContext {
return object : ScalingContext {
override val machine: SimMachine = machine
- override val cpu: ProcessingUnit = cpu
-
- override val resource: SimResourceSource = resource
+ override val cpu: SimProcessingUnit = cpu
override fun setTarget(freq: Double) {}
}
diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt
index d947b9cb..d88dec52 100644
--- a/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt
+++ b/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt
@@ -72,6 +72,26 @@ class SimMachineTest {
}
@Test
+ fun testDualSocketMachine() = runBlockingTest {
+ val clock = DelayControllerClockAdapter(this)
+ val cpuNode = machineModel.cpus[0].node
+ val machineModel = SimMachineModel(
+ 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)))
+
+ try {
+ machine.run(SimFlopsWorkload(2_000, utilization = 1.0))
+
+ // Two sockets with two cores execute 2000 MFlOps per second (500 ms)
+ assertEquals(500, currentTime)
+ } finally {
+ machine.close()
+ }
+ }
+
+ @Test
fun testUsage() = runBlockingTest {
val clock = DelayControllerClockAdapter(this)
val machine = SimBareMetalMachine(coroutineContext, clock, machineModel, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0)))
diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/DemandScalingGovernorTest.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/DemandScalingGovernorTest.kt
index c02b6285..c482d348 100644
--- a/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/DemandScalingGovernorTest.kt
+++ b/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/DemandScalingGovernorTest.kt
@@ -35,7 +35,7 @@ internal class DemandScalingGovernorTest {
fun testSetDemandLimit() {
val ctx = mockk<ScalingContext>(relaxUnitFun = true)
- every { ctx.resource.speed } returns 2100.0
+ every { ctx.cpu.speed } returns 2100.0
val logic = DemandScalingGovernor().createLogic(ctx)
diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/PStateScalingDriverTest.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/PStateScalingDriverTest.kt
index c6f233a6..bbea3ee2 100644
--- a/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/PStateScalingDriverTest.kt
+++ b/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/PStateScalingDriverTest.kt
@@ -27,10 +27,9 @@ import io.mockk.mockk
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.opendc.simulator.compute.SimBareMetalMachine
-import org.opendc.simulator.compute.model.ProcessingUnit
+import org.opendc.simulator.compute.SimProcessingUnit
import org.opendc.simulator.compute.power.ConstantPowerModel
import org.opendc.simulator.compute.power.LinearPowerModel
-import org.opendc.simulator.resources.SimResourceSource
/**
* Test suite for [PStateScalingDriver].
@@ -55,11 +54,10 @@ internal class PStateScalingDriverTest {
@Test
fun testPowerWithSingleGovernor() {
val machine = mockk<SimBareMetalMachine>()
- val cpu = mockk<ProcessingUnit>()
- val resource = mockk<SimResourceSource>()
+ val cpu = mockk<SimProcessingUnit>()
- every { cpu.frequency } returns 4100.0
- every { resource.speed } returns 1200.0
+ every { cpu.model.frequency } returns 4100.0
+ every { cpu.speed } returns 1200.0
val driver = PStateScalingDriver(
sortedMapOf(
@@ -71,7 +69,7 @@ internal class PStateScalingDriverTest {
val logic = driver.createLogic(machine)
- val scalingContext = logic.createContext(cpu, resource)
+ val scalingContext = logic.createContext(cpu)
scalingContext.setTarget(3200.0)
assertEquals(300.0, logic.computePower())
@@ -80,11 +78,10 @@ internal class PStateScalingDriverTest {
@Test
fun testPowerWithMultipleGovernors() {
val machine = mockk<SimBareMetalMachine>()
- val cpu = mockk<ProcessingUnit>()
- val resource = mockk<SimResourceSource>()
+ val cpu = mockk<SimProcessingUnit>()
- every { cpu.frequency } returns 4100.0
- every { resource.speed } returns 1200.0
+ every { cpu.model.frequency } returns 4100.0
+ every { cpu.speed } returns 1200.0
val driver = PStateScalingDriver(
sortedMapOf(
@@ -96,10 +93,10 @@ internal class PStateScalingDriverTest {
val logic = driver.createLogic(machine)
- val scalingContextA = logic.createContext(cpu, resource)
+ val scalingContextA = logic.createContext(cpu)
scalingContextA.setTarget(1000.0)
- val scalingContextB = logic.createContext(cpu, resource)
+ val scalingContextB = logic.createContext(cpu)
scalingContextB.setTarget(3400.0)
assertEquals(350.0, logic.computePower())
@@ -108,10 +105,9 @@ internal class PStateScalingDriverTest {
@Test
fun testPowerBasedOnUtilization() {
val machine = mockk<SimBareMetalMachine>()
- val cpu = mockk<ProcessingUnit>()
- val resource = mockk<SimResourceSource>()
+ val cpu = mockk<SimProcessingUnit>()
- every { cpu.frequency } returns 4200.0
+ every { cpu.model.frequency } returns 4200.0
val driver = PStateScalingDriver(
sortedMapOf(
@@ -123,13 +119,13 @@ internal class PStateScalingDriverTest {
val logic = driver.createLogic(machine)
- val scalingContext = logic.createContext(cpu, resource)
+ val scalingContext = logic.createContext(cpu)
- every { resource.speed } returns 1400.0
+ every { cpu.speed } returns 1400.0
scalingContext.setTarget(1400.0)
assertEquals(150.0, logic.computePower())
- every { resource.speed } returns 1400.0
+ every { cpu.speed } returns 1400.0
scalingContext.setTarget(4000.0)
assertEquals(235.0, logic.computePower())
}