From f3e578a2a43c99997dbf35e09debfde255a4ae22 Mon Sep 17 00:00:00 2001 From: Dante Niewenhuis Date: Sun, 3 Nov 2024 20:00:26 +0100 Subject: Rewritten the Carbon model (#260) --- .../simulator/compute/power/CarbonFragmentNew.java | 59 +++++++++++ .../simulator/compute/power/CarbonModel.java | 109 +++++++++++++++++++++ .../simulator/compute/power/SimPowerSource.java | 42 +++++++- 3 files changed, 207 insertions(+), 3 deletions(-) create mode 100644 opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonFragmentNew.java create mode 100644 opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonModel.java (limited to 'opendc-simulator/opendc-simulator-compute/src/main') diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonFragmentNew.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonFragmentNew.java new file mode 100644 index 00000000..78281a77 --- /dev/null +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonFragmentNew.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024 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.power; + +public class CarbonFragmentNew { + private long endTime; + private long startTime; + private double carbonIntensity; + + public CarbonFragmentNew(long startTime, long endTime, double carbonIntensity) { + this.setStartTime(startTime); + this.setEndTime(endTime); + this.setCarbonIntensity(carbonIntensity); + } + + public double getCarbonIntensity() { + return carbonIntensity; + } + + public void setCarbonIntensity(double carbonIntensity) { + this.carbonIntensity = carbonIntensity; + } + + public long getEndTime() { + return endTime; + } + + public void setEndTime(long endTime) { + this.endTime = endTime; + } + + public long getStartTime() { + return startTime; + } + + public void setStartTime(long startTime) { + this.startTime = startTime; + } +} diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonModel.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonModel.java new file mode 100644 index 00000000..87ced77a --- /dev/null +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/CarbonModel.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2024 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.power; + +import java.util.List; +import org.opendc.simulator.engine.FlowGraph; +import org.opendc.simulator.engine.FlowNode; + +public class CarbonModel extends FlowNode { + + private SimPowerSource powerSource; + + private long startTime = 0L; // The absolute timestamp on which the workload started + + private List fragments; + private CarbonFragmentNew current_fragment; + + private int fragment_index; + /** + * Construct a new {@link FlowNode} instance. + * + * @param parentGraph The {@link FlowGraph} this stage belongs to. + */ + public CarbonModel( + FlowGraph parentGraph, + SimPowerSource powerSource, + List carbonFragments, + long startTime) { + super(parentGraph); + + this.powerSource = powerSource; + this.startTime = startTime; + this.fragments = carbonFragments; + + this.fragment_index = 0; + this.current_fragment = this.fragments.get(this.fragment_index); + this.pushCarbonIntensity(this.current_fragment.getCarbonIntensity()); + } + + public void close() { + this.closeNode(); + } + + /** + * Convert the given time to the absolute time by adding the start of workload + * + * @param time + */ + private long getAbsoluteTime(long time) { + return time + startTime; + } + + private long getRelativeTime(long time) { + return time - startTime; + } + + private void findCorrectFragment(long absolute_time) { + + // Traverse to the previous fragment, until you reach the correct fragment + while (absolute_time < this.current_fragment.getStartTime()) { + this.current_fragment = fragments.get(--this.fragment_index); + } + + // Traverse to the next fragment, until you reach the correct fragment + while (absolute_time >= this.current_fragment.getEndTime()) { + this.current_fragment = fragments.get(++this.fragment_index); + } + } + + @Override + public long onUpdate(long now) { + long absolute_time = getAbsoluteTime(now); + + // Check if the current fragment is still the correct fragment, + // Otherwise, find the correct fragment. + if ((absolute_time < current_fragment.getStartTime()) || (absolute_time >= current_fragment.getEndTime())) { + this.findCorrectFragment(absolute_time); + + pushCarbonIntensity(current_fragment.getCarbonIntensity()); + } + + // Update again at the end of this fragment + return getRelativeTime(current_fragment.getEndTime()); + } + + private void pushCarbonIntensity(double carbonIntensity) { + this.powerSource.updateCarbonIntensity(carbonIntensity); + } +} diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/SimPowerSource.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/SimPowerSource.java index 79ff93c0..03d54ad3 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/SimPowerSource.java +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/SimPowerSource.java @@ -22,6 +22,7 @@ package org.opendc.simulator.compute.power; +import java.util.List; import org.opendc.simulator.compute.cpu.SimCpu; import org.opendc.simulator.engine.FlowEdge; import org.opendc.simulator.engine.FlowGraph; @@ -38,6 +39,10 @@ public final class SimPowerSource extends FlowNode implements FlowSupplier { private double powerSupplied = 0.0f; private double totalEnergyUsage = 0.0f; + private double carbonIntensity = 0.0f; + private double totalCarbonEmission = 0.0f; + + private CarbonModel carbonModel = null; private FlowEdge muxEdge; private double capacity = Long.MAX_VALUE; @@ -71,14 +76,21 @@ public final class SimPowerSource extends FlowNode implements FlowSupplier { return this.powerSupplied; } + public double getCarbonIntensity() { + return this.carbonIntensity; + } + /** * Return the cumulated energy usage of the machine (in J) measured at the InPort of the powers supply. */ public double getEnergyUsage() { - updateCounters(); return totalEnergyUsage; } + public double getCarbonEmission() { + return this.totalCarbonEmission; + } + @Override public double getCapacity() { return this.capacity; @@ -88,12 +100,27 @@ public final class SimPowerSource extends FlowNode implements FlowSupplier { // Constructors //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - public SimPowerSource(FlowGraph graph) { + public SimPowerSource( + FlowGraph graph, double max_capacity, List carbonFragments, long startTime) { super(graph); + this.capacity = max_capacity; + + if (carbonFragments != null) { + this.carbonModel = new CarbonModel(graph, this, carbonFragments, startTime); + } lastUpdate = this.clock.millis(); } + public void close() { + if (this.carbonModel != null) { + this.carbonModel.close(); + this.carbonModel = null; + } + + this.closeNode(); + } + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // FlowNode related functionality //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -123,8 +150,11 @@ public final class SimPowerSource extends FlowNode implements FlowSupplier { long duration = now - lastUpdate; if (duration > 0) { + double energyUsage = (this.powerSupplied * duration * 0.001); + // Compute the energy usage of the machine - this.totalEnergyUsage += (double) (this.powerSupplied * duration * 0.001); + this.totalEnergyUsage += energyUsage; + this.totalCarbonEmission += this.carbonIntensity * (energyUsage / 3600000.0); } } @@ -161,4 +191,10 @@ public final class SimPowerSource extends FlowNode implements FlowSupplier { public void removeConsumerEdge(FlowEdge consumerEdge) { this.muxEdge = null; } + + // Update the carbon intensity of the power source + public void updateCarbonIntensity(double carbonIntensity) { + this.updateCounters(); + this.carbonIntensity = carbonIntensity; + } } -- cgit v1.2.3