summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDante Niewenhuis <d.niewenhuis@hotmail.com>2024-04-22 14:32:53 +0200
committerGitHub <noreply@github.com>2024-04-22 14:32:53 +0200
commit7ffa97502d2725c1fe0a84677a654a5ea12cb454 (patch)
tree7f08b88a8e5bd1d39585b9cfcb530bd43f1a4733
parentd4c1d8468a17eb7adf8bf20949c2fdc4b2f93fec (diff)
Updated the power models and added tests (#222)
* Updated the power models and added tests * Updated test topologies
-rw-r--r--opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/TopologyFactories.kt6
-rw-r--r--opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/JSONSpecs.kt10
-rw-r--r--opendc-experiments/opendc-experiments-base/src/test/kotlin/org/opendc/experiments/base/ScenarioIntegrationTest.kt8
-rw-r--r--opendc-experiments/opendc-experiments-base/src/test/resources/env/multi.json18
-rw-r--r--opendc-experiments/opendc-experiments-base/src/test/resources/env/single.json6
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CpuPowerModels.java30
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/power/PowerModelTest.kt84
7 files changed, 121 insertions, 41 deletions
diff --git a/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/TopologyFactories.kt b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/TopologyFactories.kt
index e6b36dba..f8c7afbd 100644
--- a/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/TopologyFactories.kt
+++ b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/TopologyFactories.kt
@@ -111,7 +111,7 @@ private fun HostJSONSpec.toHostSpecs(
): HostSpec {
val unknownProcessingNode = ProcessingNode("unknown", "unknown", "unknown", cpus.sumOf { it.coreCount })
- val units = cpus.flatMap { cpu -> List(cpu.count) { cpu.toProcessingUnit(unknownProcessingNode) }.flatten() }
+ val units = cpus.flatMap { cpu -> List(cpu.count) { cpu.toProcessingUnits(unknownProcessingNode) }.flatten() }
val unknownMemoryUnit = MemoryUnit(memory.vendor, memory.modelName, memory.memorySpeed, memory.memorySize)
val machineModel =
@@ -140,7 +140,9 @@ private fun HostJSONSpec.toHostSpecs(
*/
private var globalCoreId = 0
-private fun CPUJSONSpec.toProcessingUnit(unknownProcessingNode: ProcessingNode): List<ProcessingUnit> {
+private fun CPUJSONSpec.toProcessingUnits(unknownProcessingNode: ProcessingNode): List<ProcessingUnit> {
val units = List(coreCount) { ProcessingUnit(unknownProcessingNode, globalCoreId++, coreSpeed) }
return units
+
+// return listOf(ProcessingUnit(unknownProcessingNode, globalCoreId++, coreSpeed))
}
diff --git a/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/JSONSpecs.kt b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/JSONSpecs.kt
index 5e0af541..8f73f524 100644
--- a/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/JSONSpecs.kt
+++ b/opendc-compute/opendc-compute-topology/src/main/kotlin/org/opendc/compute/topology/specs/JSONSpecs.kt
@@ -64,7 +64,7 @@ public data class HostJSONSpec(
val name: String = "Host",
val cpus: List<CPUJSONSpec>,
val memory: MemoryJSONSpec,
- val powerModel: PowerModelJSONSpec = PowerModelJSONSpec("linear", 350.0, 200.0, 400.0),
+ val powerModel: PowerModelJSONSpec = PowerModelJSONSpec("linear", 350.0, 400.0, 200.0),
val count: Int = 1,
)
@@ -109,6 +109,10 @@ public data class MemoryJSONSpec(
public data class PowerModelJSONSpec(
val modelType: String,
val power: Double = 400.0,
- val idlePower: Double,
val maxPower: Double,
-)
+ val idlePower: Double,
+) {
+ init {
+ require(maxPower >= idlePower) { "The max power of a power model can not be less than the idle power" }
+ }
+}
diff --git a/opendc-experiments/opendc-experiments-base/src/test/kotlin/org/opendc/experiments/base/ScenarioIntegrationTest.kt b/opendc-experiments/opendc-experiments-base/src/test/kotlin/org/opendc/experiments/base/ScenarioIntegrationTest.kt
index 2966c934..0ab305ee 100644
--- a/opendc-experiments/opendc-experiments-base/src/test/kotlin/org/opendc/experiments/base/ScenarioIntegrationTest.kt
+++ b/opendc-experiments/opendc-experiments-base/src/test/kotlin/org/opendc/experiments/base/ScenarioIntegrationTest.kt
@@ -125,8 +125,8 @@ class ScenarioIntegrationTest {
{ assertEquals(66977091124, monitor.activeTime) { "Incorrect active time" } },
{ assertEquals(3160267873, monitor.stealTime) { "Incorrect steal time" } },
{ assertEquals(0, monitor.lostTime) { "Incorrect lost time" } },
- { assertEquals(1.9469839319124512E7, monitor.powerDraw, 1E4) { "Incorrect power draw" } },
- { assertEquals(5.840705003360067E9, monitor.energyUsage, 1E5) { "Incorrect energy usage" } },
+ { assertEquals(2.0774585843587227E7, monitor.powerDraw, 1E4) { "Incorrect power draw" } },
+ { assertEquals(6.232122296636381E9, monitor.energyUsage, 1E4) { "Incorrect energy usage" } },
)
}
@@ -167,8 +167,8 @@ class ScenarioIntegrationTest {
{ assertEquals(9741285381, monitor.activeTime) { "Active time incorrect" } },
{ assertEquals(152, monitor.stealTime) { "Steal time incorrect" } },
{ assertEquals(0, monitor.lostTime) { "Lost time incorrect" } },
- { assertEquals(2337040.5458753705, monitor.powerDraw, 1E4) { "Incorrect power draw" } },
- { assertEquals(7.010994945790212E8, monitor.energyUsage, 1E4) { "Incorrect energy usage" } },
+ { assertEquals(2539987.394500494, monitor.powerDraw, 1E4) { "Incorrect power draw" } },
+ { assertEquals(7.619825262052509E8, monitor.energyUsage, 1E4) { "Incorrect energy usage" } },
)
}
diff --git a/opendc-experiments/opendc-experiments-base/src/test/resources/env/multi.json b/opendc-experiments/opendc-experiments-base/src/test/resources/env/multi.json
index b87877af..d23dbfe3 100644
--- a/opendc-experiments/opendc-experiments-base/src/test/resources/env/multi.json
+++ b/opendc-experiments/opendc-experiments-base/src/test/resources/env/multi.json
@@ -16,12 +16,6 @@
],
"memory": {
"memorySize": 256000
- },
- "powerModel": {
- "modelType": "linear",
- "power": 350.0,
- "maxPower": 350.0,
- "idlePower": 200.0
}
}
]
@@ -42,12 +36,6 @@
],
"memory": {
"memorySize": 64000
- },
- "powerModel": {
- "modelType": "linear",
- "power": 350.0,
- "maxPower": 350.0,
- "idlePower": 200.0
}
}
]
@@ -68,12 +56,6 @@
],
"memory": {
"memorySize": 128000
- },
- "powerModel": {
- "modelType": "linear",
- "power": 350.0,
- "maxPower": 350.0,
- "idlePower": 200.0
}
}
]
diff --git a/opendc-experiments/opendc-experiments-base/src/test/resources/env/single.json b/opendc-experiments/opendc-experiments-base/src/test/resources/env/single.json
index 9862f71a..2d68b234 100644
--- a/opendc-experiments/opendc-experiments-base/src/test/resources/env/single.json
+++ b/opendc-experiments/opendc-experiments-base/src/test/resources/env/single.json
@@ -16,12 +16,6 @@
],
"memory": {
"memorySize": 128000
- },
- "powerModel": {
- "modelType": "linear",
- "power": 350.0,
- "maxPower": 350.0,
- "idlePower": 200.0
}
}
]
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CpuPowerModels.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CpuPowerModels.java
index 7ba9eaed..537fb8d8 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CpuPowerModels.java
+++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CpuPowerModels.java
@@ -163,6 +163,12 @@ public class CpuPowerModels {
this.idlePower = idlePower;
}
+ // Clamps the provided utilization in the range of 0.0 and 1.0
+ // This is done to avoid floating point errors
+ public double clampUtilization(double utilization) {
+ return Math.max(0.0, Math.min(1.0, utilization));
+ }
+
@Override
public String toString() {
return getClass().getSimpleName() + "[max=" + maxPower + ",idle=" + idlePower + "]";
@@ -174,12 +180,14 @@ public class CpuPowerModels {
SqrtPowerModel(double maxPower, double idlePower) {
super(maxPower, idlePower);
- this.factor = (maxPower - idlePower) / Math.sqrt(100);
+ this.factor = (maxPower - idlePower);
}
@Override
public double computePower(double utilization) {
- return idlePower + factor * Math.sqrt(utilization * 100);
+ utilization = clampUtilization(utilization);
+
+ return idlePower + factor * Math.sqrt(utilization);
}
@Override
@@ -198,12 +206,14 @@ public class CpuPowerModels {
LinearPowerModel(double maxPower, double idlePower) {
super(maxPower, idlePower);
- this.factor = (maxPower - idlePower) / 100;
+ this.factor = maxPower - idlePower;
}
@Override
public double computePower(double utilization) {
- return idlePower + factor * utilization * 100;
+ utilization = clampUtilization(utilization);
+
+ return idlePower + factor * utilization;
}
@Override
@@ -222,12 +232,14 @@ public class CpuPowerModels {
SquarePowerModel(double maxPower, double idlePower) {
super(maxPower, idlePower);
- this.factor = (maxPower - idlePower) / Math.pow(100, 2);
+ this.factor = (maxPower - idlePower);
}
@Override
public double computePower(double utilization) {
- return idlePower + factor * Math.pow(utilization * 100, 2);
+ utilization = clampUtilization(utilization);
+
+ return idlePower + factor * Math.pow(utilization, 2);
}
@Override
@@ -246,12 +258,14 @@ public class CpuPowerModels {
CubicPowerModel(double maxPower, double idlePower) {
super(maxPower, idlePower);
- this.factor = (maxPower - idlePower) / Math.pow(100, 3);
+ this.factor = (maxPower - idlePower);
}
@Override
public double computePower(double utilization) {
- return idlePower + factor * Math.pow(utilization * 100, 3);
+ utilization = clampUtilization(utilization);
+
+ return idlePower + factor * Math.pow(utilization, 3);
}
@Override
diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/power/PowerModelTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/power/PowerModelTest.kt
index e85758ae..e3bea821 100644
--- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/power/PowerModelTest.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/power/PowerModelTest.kt
@@ -78,6 +78,90 @@ internal class PowerModelTest {
)
}
+ @Test
+ fun `test linear model`() {
+ val powerModel = CpuPowerModels.linear(400.0, 200.0)
+
+ assertAll(
+ { assertEquals(200.0, powerModel.computePower(-0.1)) },
+ { assertEquals(200.0, powerModel.computePower(0.0)) },
+ { assertEquals(220.0, powerModel.computePower(0.1)) },
+ { assertEquals(240.0, powerModel.computePower(0.2)) },
+ { assertEquals(260.0, powerModel.computePower(0.3)) },
+ { assertEquals(280.0, powerModel.computePower(0.4)) },
+ { assertEquals(300.0, powerModel.computePower(0.5)) },
+ { assertEquals(320.0, powerModel.computePower(0.6)) },
+ { assertEquals(340.0, powerModel.computePower(0.7)) },
+ { assertEquals(360.0, powerModel.computePower(0.8)) },
+ { assertEquals(380.0, powerModel.computePower(0.9)) },
+ { assertEquals(400.0, powerModel.computePower(1.0)) },
+ { assertEquals(400.0, powerModel.computePower(1.1)) },
+ )
+ }
+
+ @Test
+ fun `test sqrt model`() {
+ val powerModel = CpuPowerModels.sqrt(400.0, 200.0)
+
+ assertAll(
+ { assertEquals(200.0, powerModel.computePower(-1.0), 1.0) },
+ { assertEquals(200.0, powerModel.computePower(0.0), 1.0) },
+ { assertEquals(263.0, powerModel.computePower(0.1), 1.0) },
+ { assertEquals(289.0, powerModel.computePower(0.2), 1.0) },
+ { assertEquals(309.0, powerModel.computePower(0.3), 1.0) },
+ { assertEquals(326.0, powerModel.computePower(0.4), 1.0) },
+ { assertEquals(341.0, powerModel.computePower(0.5), 1.0) },
+ { assertEquals(354.0, powerModel.computePower(0.6), 1.0) },
+ { assertEquals(367.0, powerModel.computePower(0.7), 1.0) },
+ { assertEquals(378.0, powerModel.computePower(0.8), 1.0) },
+ { assertEquals(389.0, powerModel.computePower(0.9), 1.0) },
+ { assertEquals(400.0, powerModel.computePower(1.0), 1.0) },
+ { assertEquals(400.0, powerModel.computePower(1.1), 1.0) },
+ )
+ }
+
+ @Test
+ fun `test square model`() {
+ val powerModel = CpuPowerModels.square(400.0, 200.0)
+
+ assertAll(
+ { assertEquals(200.0, powerModel.computePower(-1.0), 1.0) },
+ { assertEquals(200.0, powerModel.computePower(0.0), 1.0) },
+ { assertEquals(202.0, powerModel.computePower(0.1), 1.0) },
+ { assertEquals(208.0, powerModel.computePower(0.2), 1.0) },
+ { assertEquals(218.0, powerModel.computePower(0.3), 1.0) },
+ { assertEquals(232.0, powerModel.computePower(0.4), 1.0) },
+ { assertEquals(250.0, powerModel.computePower(0.5), 1.0) },
+ { assertEquals(272.0, powerModel.computePower(0.6), 1.0) },
+ { assertEquals(298.0, powerModel.computePower(0.7), 1.0) },
+ { assertEquals(328.0, powerModel.computePower(0.8), 1.0) },
+ { assertEquals(362.0, powerModel.computePower(0.9), 1.0) },
+ { assertEquals(400.0, powerModel.computePower(1.0), 1.0) },
+ { assertEquals(400.0, powerModel.computePower(1.1), 1.0) },
+ )
+ }
+
+ @Test
+ fun `test cubic model`() {
+ val powerModel = CpuPowerModels.cubic(400.0, 200.0)
+
+ assertAll(
+ { assertEquals(200.0, powerModel.computePower(-1.0), 1.0) },
+ { assertEquals(200.0, powerModel.computePower(0.0), 1.0) },
+ { assertEquals(200.0, powerModel.computePower(0.1), 1.0) },
+ { assertEquals(201.0, powerModel.computePower(0.2), 1.0) },
+ { assertEquals(205.0, powerModel.computePower(0.3), 1.0) },
+ { assertEquals(212.0, powerModel.computePower(0.4), 1.0) },
+ { assertEquals(225.0, powerModel.computePower(0.5), 1.0) },
+ { assertEquals(243.0, powerModel.computePower(0.6), 1.0) },
+ { assertEquals(268.0, powerModel.computePower(0.7), 1.0) },
+ { assertEquals(302.0, powerModel.computePower(0.8), 1.0) },
+ { assertEquals(345.0, powerModel.computePower(0.9), 1.0) },
+ { assertEquals(400.0, powerModel.computePower(1.0), 1.0) },
+ { assertEquals(400.0, powerModel.computePower(1.1), 1.0) },
+ )
+ }
+
@Suppress("unused")
private companion object {
@JvmStatic