summaryrefslogtreecommitdiff
path: root/simulator
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2021-04-07 11:11:19 +0200
committerFabian Mastenbroek <mail.fabianm@gmail.com>2021-04-07 12:13:16 +0200
commit3860d9e1c042eefacd5accb771cf47990090f649 (patch)
tree6ea7f7480c3e75dc258176dfca904e98808d138c /simulator
parentf3384ca33f84fc261aeb20ca7752ab052971dcf4 (diff)
simulator: Add tests for CPUFreq subsystem
Diffstat (limited to 'simulator')
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/PStateScalingDriver.kt13
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ScalingGovernor.kt2
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt12
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/DemandScalingGovernorTest.kt48
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/PStateScalingDriverTest.kt136
-rw-r--r--simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/power/PowerModelTest.kt8
6 files changed, 209 insertions, 10 deletions
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 8f3eacea..d109e4d8 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
@@ -28,6 +28,7 @@ import org.opendc.simulator.compute.power.PowerModel
import org.opendc.simulator.resources.SimResourceSource
import java.util.*
import kotlin.math.max
+import kotlin.math.min
/**
* A [ScalingDriver] that scales the frequency of the processor based on a discrete set of frequencies.
@@ -53,18 +54,18 @@ public class PStateScalingDriver(states: Map<Double, PowerModel>) : ScalingDrive
}
override fun computePower(): Double {
- var freq = 0.0
+ var targetFreq = 0.0
var totalSpeed = 0.0
- var totalFreq = 0.0
for (ctx in contexts) {
- freq = max(ctx.target, freq)
+ targetFreq = max(ctx.target, targetFreq)
totalSpeed += ctx.resource.speed.value
- totalFreq += ctx.target
}
- val (_, model) = states.ceilingEntry(freq)
- return model.computePower(totalSpeed / totalFreq)
+ val maxFreq = states.lastKey()
+ val (actualFreq, model) = states.ceilingEntry(min(maxFreq, targetFreq))
+ val utilization = totalSpeed / (actualFreq * contexts.size)
+ return model.computePower(utilization)
}
override fun toString(): String = "PStateScalingDriver.Logic"
diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ScalingGovernor.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ScalingGovernor.kt
index 9c6eb9ed..c9aea580 100644
--- a/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ScalingGovernor.kt
+++ b/simulator/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/cpufreq/ScalingGovernor.kt
@@ -47,7 +47,7 @@ public interface ScalingGovernor {
public fun onStart() {}
/**
- * This method is invoked when
+ * This method is invoked when the governor should re-decide the frequency limits.
*/
public fun onLimit() {}
}
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 13f7f9ea..d947b9cb 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
@@ -28,6 +28,8 @@ import kotlinx.coroutines.test.runBlockingTest
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.assertDoesNotThrow
+import org.junit.jupiter.api.assertThrows
import org.opendc.simulator.compute.cpufreq.PerformanceScalingGovernor
import org.opendc.simulator.compute.cpufreq.SimpleScalingDriver
import org.opendc.simulator.compute.model.MemoryUnit
@@ -86,4 +88,14 @@ class SimMachineTest {
machine.close()
}
}
+
+ @Test
+ fun testClose() = runBlockingTest {
+ val clock = DelayControllerClockAdapter(this)
+ val machine = SimBareMetalMachine(coroutineContext, clock, machineModel, PerformanceScalingGovernor(), SimpleScalingDriver(ConstantPowerModel(0.0)))
+
+ machine.close()
+ assertDoesNotThrow { machine.close() }
+ assertThrows<IllegalStateException> { machine.run(SimFlopsWorkload(2_000, utilization = 1.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
new file mode 100644
index 00000000..19c06126
--- /dev/null
+++ b/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/DemandScalingGovernorTest.kt
@@ -0,0 +1,48 @@
+/*
+ * 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.cpufreq
+
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.verify
+import org.junit.jupiter.api.Test
+
+/**
+ * Test suite for the [DemandScalingGovernor]
+ */
+internal class DemandScalingGovernorTest {
+ @Test
+ fun testSetDemandLimit() {
+ val ctx = mockk<ScalingContext>(relaxUnitFun = true)
+
+ every { ctx.resource.speed.value } returns 2100.0
+
+ val logic = DemandScalingGovernor().createLogic(ctx)
+
+ logic.onStart()
+ verify(exactly = 0) { ctx.setTarget(any()) }
+
+ logic.onLimit()
+ verify(exactly = 1) { ctx.setTarget(2100.0) }
+ }
+}
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
new file mode 100644
index 00000000..5c30bc1f
--- /dev/null
+++ b/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/cpufreq/PStateScalingDriverTest.kt
@@ -0,0 +1,136 @@
+/*
+ * 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.cpufreq
+
+import io.mockk.every
+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.power.ConstantPowerModel
+import org.opendc.simulator.compute.power.LinearPowerModel
+import org.opendc.simulator.resources.SimResourceSource
+
+/**
+ * Test suite for [PStateScalingDriver].
+ */
+internal class PStateScalingDriverTest {
+ @Test
+ fun testPowerWithoutGovernor() {
+ val machine = mockk<SimBareMetalMachine>()
+
+ val driver = PStateScalingDriver(
+ sortedMapOf(
+ 2800.0 to ConstantPowerModel(200.0),
+ 3300.0 to ConstantPowerModel(300.0),
+ 3600.0 to ConstantPowerModel(350.0),
+ )
+ )
+
+ val logic = driver.createLogic(machine)
+ assertEquals(200.0, logic.computePower())
+ }
+
+ @Test
+ fun testPowerWithSingleGovernor() {
+ val machine = mockk<SimBareMetalMachine>()
+ val cpu = mockk<ProcessingUnit>()
+ val resource = mockk<SimResourceSource>()
+
+ every { cpu.frequency } returns 4100.0
+ every { resource.speed.value } returns 1200.0
+
+ val driver = PStateScalingDriver(
+ sortedMapOf(
+ 2800.0 to ConstantPowerModel(200.0),
+ 3300.0 to ConstantPowerModel(300.0),
+ 3600.0 to ConstantPowerModel(350.0),
+ )
+ )
+
+ val logic = driver.createLogic(machine)
+
+ val scalingContext = logic.createContext(cpu, resource)
+ scalingContext.setTarget(3200.0)
+
+ assertEquals(300.0, logic.computePower())
+ }
+
+ @Test
+ fun testPowerWithMultipleGovernors() {
+ val machine = mockk<SimBareMetalMachine>()
+ val cpu = mockk<ProcessingUnit>()
+ val resource = mockk<SimResourceSource>()
+
+ every { cpu.frequency } returns 4100.0
+ every { resource.speed.value } returns 1200.0
+
+ val driver = PStateScalingDriver(
+ sortedMapOf(
+ 2800.0 to ConstantPowerModel(200.0),
+ 3300.0 to ConstantPowerModel(300.0),
+ 3600.0 to ConstantPowerModel(350.0),
+ )
+ )
+
+ val logic = driver.createLogic(machine)
+
+ val scalingContextA = logic.createContext(cpu, resource)
+ scalingContextA.setTarget(1000.0)
+
+ val scalingContextB = logic.createContext(cpu, resource)
+ scalingContextB.setTarget(3400.0)
+
+ assertEquals(350.0, logic.computePower())
+ }
+
+ @Test
+ fun testPowerBasedOnUtilization() {
+ val machine = mockk<SimBareMetalMachine>()
+ val cpu = mockk<ProcessingUnit>()
+ val resource = mockk<SimResourceSource>()
+
+ every { cpu.frequency } returns 4200.0
+
+ val driver = PStateScalingDriver(
+ sortedMapOf(
+ 2800.0 to LinearPowerModel(200.0, 100.0),
+ 3300.0 to LinearPowerModel(250.0, 150.0),
+ 4000.0 to LinearPowerModel(300.0, 200.0),
+ )
+ )
+
+ val logic = driver.createLogic(machine)
+
+ val scalingContext = logic.createContext(cpu, resource)
+
+ every { resource.speed.value } returns 1400.0
+ scalingContext.setTarget(1400.0)
+ assertEquals(150.0, logic.computePower())
+
+ every { resource.speed.value } returns 1400.0
+ scalingContext.setTarget(4000.0)
+ assertEquals(235.0, logic.computePower())
+ }
+}
diff --git a/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/power/PowerModelTest.kt b/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/power/PowerModelTest.kt
index 8ec9910c..439be274 100644
--- a/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/power/PowerModelTest.kt
+++ b/simulator/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/power/PowerModelTest.kt
@@ -3,7 +3,6 @@ package org.opendc.simulator.compute.power
import org.junit.jupiter.api.Assertions.assertAll
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.assertThrows
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.MethodSource
@@ -31,8 +30,11 @@ internal class PowerModelTest {
expectedPowerConsumption: Double
) {
val zeroPowerModel = ZeroIdlePowerDecorator(powerModel)
- val computedPowerConsumption = zeroPowerModel.computePower(0.0)
- assertEquals(0.0, computedPowerConsumption)
+
+ assertAll(
+ { assertEquals(expectedPowerConsumption, zeroPowerModel.computePower(cpuUtil), epsilon) },
+ { assertEquals(0.0, zeroPowerModel.computePower(0.0)) }
+ )
}
@Test