Skip to content

Commit

Permalink
Updated the power models and added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
DanteNiewenhuis committed Apr 22, 2024
1 parent d652fa2 commit 9360cb4
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,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 =
Expand Down Expand Up @@ -134,7 +134,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))
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,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,
)

Expand Down Expand Up @@ -110,4 +110,8 @@ public data class PowerModelJSONSpec(
val power: Double = 400.0,
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" }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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(2.5892214E7, monitor.powerDraw, 1E4) { "Incorrect power draw" } },
{ assertEquals(7.7672373E9, monitor.energyUsage, 1E4) { "Incorrect energy usage" } },
{ assertEquals(2.0774585843587227E7, monitor.powerDraw, 1E4) { "Incorrect power draw" } },
{ assertEquals(6.232122296636381E9, monitor.energyUsage, 1E4) { "Incorrect energy usage" } },
)
}

Expand Down Expand Up @@ -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(2644612.0, monitor.powerDraw, 1E4) { "Incorrect power draw" } },
{ assertEquals(7.9336867E8, monitor.energyUsage, 1E4) { "Incorrect energy usage" } },
{ assertEquals(2539987.394500494, monitor.powerDraw, 1E4) { "Incorrect power draw" } },
{ assertEquals(7.619825262052509E8, monitor.energyUsage, 1E4) { "Incorrect energy usage" } },
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,12 @@ private abstract static class MaxIdlePowerModel implements CpuPowerModel {
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 + "]";
Expand All @@ -169,12 +175,14 @@ private static final class SqrtPowerModel extends MaxIdlePowerModel {

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);
}
}

Expand All @@ -183,12 +191,14 @@ private static final class LinearPowerModel extends MaxIdlePowerModel {

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;
}
}

Expand All @@ -197,12 +207,14 @@ private static final class SquarePowerModel extends MaxIdlePowerModel {

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);
}
}

Expand All @@ -211,12 +223,14 @@ private static final class CubicPowerModel extends MaxIdlePowerModel {

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);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 9360cb4

Please sign in to comment.