diff options
Diffstat (limited to 'opendc-simulator')
11 files changed, 100 insertions, 170 deletions
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/cpu/SimCpu.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/cpu/SimCpu.java index 5669eb16..52fc6093 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/cpu/SimCpu.java +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/cpu/SimCpu.java @@ -22,6 +22,8 @@ package org.opendc.simulator.compute.cpu; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.List; import java.util.Map; import org.opendc.common.ResourceType; @@ -140,7 +142,10 @@ public final class SimCpu extends FlowNode implements FlowSupplier, FlowConsumer updateCounters(now); // Check if supply == demand - if (this.currentPowerDemand != this.currentPowerSupplied) { + // using big decimal to avoid floating point precision issues + if (!new BigDecimal(this.currentPowerDemand) + .setScale(5, RoundingMode.HALF_UP) + .equals(new BigDecimal(this.currentPowerSupplied).setScale(5, RoundingMode.HALF_UP))) { this.pushOutgoingDemand(this.psuEdge, this.currentPowerDemand); return Long.MAX_VALUE; @@ -182,6 +187,7 @@ public final class SimCpu extends FlowNode implements FlowSupplier, FlowConsumer this.performanceCounters.setDemand(this.currentCpuDemand); this.performanceCounters.setSupply(this.currentCpuSupplied); this.performanceCounters.setCapacity(this.maxCapacity); + this.performanceCounters.setPowerDraw(this.currentPowerDemand); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -195,7 +201,7 @@ public final class SimCpu extends FlowNode implements FlowSupplier, FlowConsumer public void pushOutgoingDemand(FlowEdge supplierEdge, double newPowerDemand) { updateCounters(); this.currentPowerDemand = newPowerDemand; - this.psuEdge.pushDemand(newPowerDemand, false, ResourceType.CPU); + this.psuEdge.pushDemand(newPowerDemand, false, ResourceType.POWER); } /** diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/gpu/SimGpu.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/gpu/SimGpu.java index 99317a08..a5fccf6c 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/gpu/SimGpu.java +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/gpu/SimGpu.java @@ -22,6 +22,8 @@ package org.opendc.simulator.compute.gpu; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.List; import java.util.Map; import org.opendc.common.ResourceType; @@ -144,7 +146,10 @@ public final class SimGpu extends FlowNode implements FlowSupplier, FlowConsumer updateCounters(now); // Check if supply == demand - if (this.currentPowerDemand != this.currentPowerSupplied) { + // using big decimal to avoid floating point precision issues + if (!new BigDecimal(this.currentPowerDemand) + .setScale(5, RoundingMode.HALF_UP) + .equals(new BigDecimal(this.currentPowerSupplied).setScale(5, RoundingMode.HALF_UP))) { this.pushOutgoingDemand(this.psuEdge, this.currentPowerDemand); return Long.MAX_VALUE; @@ -185,6 +190,7 @@ public final class SimGpu extends FlowNode implements FlowSupplier, FlowConsumer this.performanceCounters.setDemand(this.currentGpuDemand); this.performanceCounters.setSupply(this.currentGpuSupplied); this.performanceCounters.setCapacity(this.maxCapacity); + this.performanceCounters.setPowerDraw(this.currentPowerSupplied); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -198,7 +204,7 @@ public final class SimGpu extends FlowNode implements FlowSupplier, FlowConsumer public void pushOutgoingDemand(FlowEdge supplierEdge, double newPowerDemand) { updateCounters(); this.currentPowerDemand = newPowerDemand; - this.psuEdge.pushDemand(newPowerDemand, false, ResourceType.GPU); + this.psuEdge.pushDemand(newPowerDemand, false, ResourceType.POWER); } /** @@ -209,7 +215,7 @@ public final class SimGpu extends FlowNode implements FlowSupplier, FlowConsumer updateCounters(); this.currentGpuSupplied = newGpuSupply; - this.distributorEdge.pushSupply(newGpuSupply, true, ResourceType.GPU); + this.distributorEdge.pushSupply(newGpuSupply, true, ResourceType.POWER); } /** diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/machine/PerformanceCounters.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/machine/PerformanceCounters.java index 93033bc0..013846cd 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/machine/PerformanceCounters.java +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/machine/PerformanceCounters.java @@ -32,6 +32,7 @@ public class PerformanceCounters { private double capacity = 0.0f; private double demand = 0.0f; private double supply = 0.0f; + private double powerDraw = 0.0f; public long getActiveTime() { return this.activeTime; @@ -61,6 +62,10 @@ public class PerformanceCounters { return this.supply; } + public double getPowerDraw() { + return powerDraw; + } + public void setActiveTime(long activeTime) { this.activeTime = activeTime; } @@ -89,6 +94,10 @@ public class PerformanceCounters { this.supply = supply; } + public void setPowerDraw(double powerDraw) { + this.powerDraw = powerDraw; + } + public void addActiveTime(long activeTime) { this.activeTime += activeTime; } @@ -116,4 +125,8 @@ public class PerformanceCounters { public void addSupply(double supply) { this.supply += supply; } + + public void addPowerDraw(double powerDraw) { + this.powerDraw += powerDraw; + } } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/machine/SimMachine.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/machine/SimMachine.java index 7158356a..e56e1b5c 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/machine/SimMachine.java +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/machine/SimMachine.java @@ -47,6 +47,7 @@ import org.opendc.simulator.engine.graph.FlowEdge; import org.opendc.simulator.engine.graph.FlowNode; import org.opendc.simulator.engine.graph.FlowSupplier; import org.opendc.simulator.engine.graph.distributionPolicies.FlowDistributorFactory; +import org.opendc.simulator.engine.graph.distributionPolicies.MaxMinFairnessFlowDistributor; /** * A machine that is able to execute {@link SimWorkload} objects. @@ -207,6 +208,8 @@ public class SimMachine { // Create the psu and cpu and connect them this.psu = new SimPsu(engine); new FlowEdge(this.psu, powerDistributor); + this.distributors.put(ResourceType.POWER, new MaxMinFairnessFlowDistributor(engine)); // Maybe First fit + new FlowEdge(this.distributors.get(ResourceType.POWER), this.psu); this.computeResources.put( ResourceType.CPU, @@ -215,7 +218,7 @@ public class SimMachine { // Connect the CPU to the PSU new FlowEdge( (FlowConsumer) this.computeResources.get(ResourceType.CPU).getFirst(), - this.psu, + (FlowSupplier) this.distributors.get(ResourceType.POWER), ResourceType.POWER, 0, -1); @@ -253,7 +256,12 @@ public class SimMachine { gpuModel.getId(), gpuModel.getId()); // Connect the GPU to the PSU - new FlowEdge(gpu, this.psu, ResourceType.POWER, gpuModel.getId(), gpuModel.getId()); + new FlowEdge( + gpu, + this.distributors.get(ResourceType.POWER), + ResourceType.POWER, + gpuModel.getId(), + gpuModel.getId()); } this.computeResources.put(ResourceType.GPU, gpus); } diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/SimPsu.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/SimPsu.java index f40f4fec..ec4089cd 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/SimPsu.java +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/power/SimPsu.java @@ -22,8 +22,6 @@ package org.opendc.simulator.compute.power; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; import org.opendc.common.ResourceType; @@ -33,27 +31,21 @@ import org.opendc.simulator.engine.graph.FlowConsumer; import org.opendc.simulator.engine.graph.FlowEdge; import org.opendc.simulator.engine.graph.FlowNode; import org.opendc.simulator.engine.graph.FlowSupplier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * A {@link SimPsu} implementation that estimates the power consumption based on CPU usage. */ public final class SimPsu extends FlowNode implements FlowSupplier, FlowConsumer { - private static final Logger LOGGER = LoggerFactory.getLogger(SimPsu.class); private long lastUpdate; - private final HashMap<ResourceType, HashMap<Integer, Double>> powerDemandsPerResource = new HashMap<>(); - private final HashMap<ResourceType, HashMap<Integer, Double>> powerSuppliedPerResource = new HashMap<>(); - - private double totalPowerDemand = 0.0; - private double totalPowerSupplied = 0.0; + private double powerDemand = 0.0; + private double powerSupplied = 0.0; private double totalEnergyUsage = 0.0; - private final HashMap<ResourceType, HashMap<Integer, FlowEdge>> resourceEdges = new HashMap<>(); + private FlowEdge cpuEdge; private FlowEdge powerSupplyEdge; - private final double capacity = Long.MAX_VALUE; + private double capacity = Long.MAX_VALUE; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Basic Getters and Setters @@ -65,8 +57,7 @@ public final class SimPsu extends FlowNode implements FlowSupplier, FlowConsumer * @return <code>true</code> if the InPort is connected to an OutPort, <code>false</code> otherwise. */ public boolean isConnected() { - return !this.resourceEdges.isEmpty() - && this.resourceEdges.values().stream().anyMatch(list -> !list.isEmpty()); + return cpuEdge != null; } /** @@ -75,51 +66,14 @@ public final class SimPsu extends FlowNode implements FlowSupplier, FlowConsumer * This method provides access to the power consumption of the machine before PSU losses are applied. */ public double getPowerDemand() { - return this.totalPowerDemand; - } - - /** - * Return the power demand of the machine (in W) measured in the PSU for a specific resource type. - * <p> - * This method provides access to the power consumption of the machine before PSU losses are applied. - */ - public double getPowerDemand(ResourceType resourceType) { - // return this.powerDemandsPerResource.get(resourceType).stream().mapToDouble(Double::doubleValue).sum(); - return this.powerDemandsPerResource.get(resourceType).values().stream() - .mapToDouble(Double::doubleValue) - .sum(); - } - - /** - * Return the power demand of the machine (in W) measured in the PSU for a specific resource type for a specific resource. - * <p> - * This method provides access to the power consumption of the machine before PSU losses are applied. - */ - public double getPowerDemand(ResourceType resourceType, int id) { - return this.powerDemandsPerResource.get(resourceType).get(id); + return this.powerDemand; } /** * Return the instantaneous power usage of the machine (in W) measured at the InPort of the power supply. */ public double getPowerDraw() { - return this.totalPowerSupplied; - } - - /** - * Return the instantaneous power usage of the machine (in W) measured at the InPort of the power supply for a specific resource type. - */ - public double getPowerDraw(ResourceType resourceType) { - return this.powerSuppliedPerResource.get(resourceType).values().stream() - .mapToDouble(Double::doubleValue) - .sum(); - } - - /** - * Return the instantaneous power usage of the machine (in W) measured at the InPort of the power supply for a specific resource type for a specific resource. - */ - public double getPowerDraw(ResourceType resourceType, int id) { - return this.powerSuppliedPerResource.get(resourceType).get(id); + return this.powerSupplied; } /** @@ -152,26 +106,10 @@ public final class SimPsu extends FlowNode implements FlowSupplier, FlowConsumer @Override public long onUpdate(long now) { updateCounters(); - for (ResourceType resourceType : this.resourceEdges.keySet()) { - HashMap<Integer, FlowEdge> edges = this.resourceEdges.get(resourceType); - if (edges != null && !edges.isEmpty()) { - for (FlowEdge edge : edges.values()) { - // If the edge is null, it means that the edge has been removed -> no update is needed - if (edge == null) { - continue; - } - - int consumerIndex = edge.getConsumerIndex() == -1 ? 0 : edge.getConsumerIndex(); - double powerDemand = - this.powerDemandsPerResource.get(resourceType).get(consumerIndex); - double powerSupplied = - this.powerSuppliedPerResource.get(resourceType).get(consumerIndex); - - if (powerDemand != powerSupplied) { - edge.pushSupply(powerDemand); - } - } - } + double powerSupply = this.powerDemand; + + if (powerSupply != this.powerSupplied) { + this.pushOutgoingSupply(this.cpuEdge, powerSupply); } return Long.MAX_VALUE; @@ -190,12 +128,8 @@ public final class SimPsu extends FlowNode implements FlowSupplier, FlowConsumer long duration = now - lastUpdate; if (duration > 0) { - for (ResourceType resourceType : this.powerSuppliedPerResource.keySet()) { - for (double powerSupplied : - this.powerSuppliedPerResource.get(resourceType).values()) { - this.totalEnergyUsage += (powerSupplied * duration * 0.001); - } - } + // Compute the energy usage of the psu + this.totalEnergyUsage += (this.powerSupplied * duration * 0.001); } } @@ -205,77 +139,37 @@ public final class SimPsu extends FlowNode implements FlowSupplier, FlowConsumer @Override public void pushOutgoingDemand(FlowEdge supplierEdge, double newDemand) { - this.powerSupplyEdge.pushDemand(newDemand); + this.powerDemand = newDemand; + powerSupplyEdge.pushDemand(newDemand); } @Override public void pushOutgoingSupply(FlowEdge consumerEdge, double newSupply) { - this.pushOutgoingSupply(consumerEdge, newSupply, consumerEdge.getConsumerResourceType()); + this.powerSupplied = newSupply; + cpuEdge.pushSupply(newSupply); } @Override - public void pushOutgoingSupply(FlowEdge consumerEdge, double newSupply, ResourceType resourceType) { - int consumerIndex = consumerEdge.getConsumerIndex() == -1 ? 0 : consumerEdge.getConsumerIndex(); - - double previousSupply = this.powerSuppliedPerResource.get(resourceType).get(consumerIndex); - this.totalPowerSupplied += newSupply - previousSupply; + public void handleIncomingDemand(FlowEdge consumerEdge, double newPowerDemand) { - this.powerSuppliedPerResource.get(resourceType).put(consumerIndex, newSupply); + updateCounters(); + this.powerDemand = newPowerDemand; - consumerEdge.pushSupply(newSupply, false, resourceType); + pushOutgoingDemand(this.powerSupplyEdge, newPowerDemand); } @Override - public void handleIncomingDemand(FlowEdge consumerEdge, double newDemand) { - handleIncomingDemand(consumerEdge, newDemand, consumerEdge.getConsumerResourceType()); - } + public void handleIncomingSupply(FlowEdge supplierEdge, double newPowerSupply) { - @Override - public void handleIncomingDemand(FlowEdge consumerEdge, double newPowerDemand, ResourceType resourceType) { updateCounters(); - int consumerIndex = consumerEdge.getConsumerIndex() == -1 ? 0 : consumerEdge.getConsumerIndex(); - - double previousPowerDemand = - this.powerDemandsPerResource.get(resourceType).get(consumerIndex); - this.totalPowerDemand += newPowerDemand - previousPowerDemand; + this.powerSupplied = newPowerSupply; - this.powerDemandsPerResource.get(resourceType).put(consumerIndex, newPowerDemand); - - pushOutgoingDemand(this.powerSupplyEdge, totalPowerDemand); - } - - @Override - public void handleIncomingSupply(FlowEdge supplierEdge, double newSupply) { - updateCounters(); - for (ResourceType resourceType : this.resourceEdges.keySet()) { - for (FlowEdge edge : this.resourceEdges.get(resourceType).values()) { - // If the edge is null, it means that the edge has been removed -> no update is needed - if (edge == null) { - continue; - } - int consumerIndex = edge.getConsumerIndex() == -1 ? 0 : edge.getConsumerIndex(); - double outgoingSupply = - Math.min(this.powerDemandsPerResource.get(resourceType).get(consumerIndex), newSupply); - pushOutgoingSupply(edge, outgoingSupply, resourceType); - } - } + pushOutgoingSupply(this.cpuEdge, newPowerSupply); } @Override public void addConsumerEdge(FlowEdge consumerEdge) { - - ResourceType consumerResourceType = consumerEdge.getConsumerResourceType(); - int consumerIndex = consumerEdge.getConsumerIndex() == -1 ? 0 : consumerEdge.getConsumerIndex(); - - if (!this.resourceEdges.containsKey(consumerResourceType)) { - this.resourceEdges.put(consumerResourceType, new HashMap<>()); - this.powerDemandsPerResource.put(consumerResourceType, new HashMap<>()); - this.powerSuppliedPerResource.put(consumerResourceType, new HashMap<>()); - } - - this.resourceEdges.get(consumerResourceType).put(consumerIndex, consumerEdge); - this.powerDemandsPerResource.get(consumerResourceType).put(consumerIndex, 0.0); - this.powerSuppliedPerResource.get(consumerResourceType).put(consumerIndex, 0.0); + this.cpuEdge = consumerEdge; } @Override @@ -285,20 +179,7 @@ public final class SimPsu extends FlowNode implements FlowSupplier, FlowConsumer @Override public void removeConsumerEdge(FlowEdge consumerEdge) { - ResourceType resourceType = consumerEdge.getConsumerResourceType(); - int consumerIndex = consumerEdge.getConsumerIndex() == -1 ? 0 : consumerEdge.getConsumerIndex(); - - if (this.resourceEdges.containsKey(resourceType)) { - this.resourceEdges.get(resourceType).put(consumerIndex, null); - - this.totalPowerDemand -= - this.powerDemandsPerResource.get(resourceType).get(consumerIndex); - this.powerDemandsPerResource.get(resourceType).put(consumerIndex, 0.0); - - this.totalPowerSupplied -= - this.powerSuppliedPerResource.get(resourceType).get(consumerIndex); - this.powerSuppliedPerResource.get(resourceType).put(consumerIndex, 0.0); - } + this.cpuEdge = null; } @Override @@ -308,14 +189,7 @@ public final class SimPsu extends FlowNode implements FlowSupplier, FlowConsumer @Override public Map<FlowEdge.NodeType, List<FlowEdge>> getConnectedEdges() { - List<FlowEdge> supplyingEdges = new ArrayList<>(); - for (ResourceType resourceType : this.resourceEdges.keySet()) { - List<FlowEdge> edges = - this.resourceEdges.get(resourceType).values().stream().toList(); - if (edges != null && !edges.isEmpty()) { - supplyingEdges.addAll(edges); - } - } + List<FlowEdge> supplyingEdges = cpuEdge != null ? List.of(cpuEdge) : List.of(); List<FlowEdge> consumingEdges = powerSupplyEdge != null ? List.of(powerSupplyEdge) : List.of(); return Map.of( diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/trace/SimTraceWorkload.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/trace/SimTraceWorkload.java index 95487476..39e17819 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/trace/SimTraceWorkload.java +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/trace/SimTraceWorkload.java @@ -165,7 +165,7 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { // The amount of work done since last update double finishedWork = this.scalingPolicy.getFinishedWork( this.resourcesDemand.get(resourceType), this.resourcesSupplied.get(resourceType), passedTime); - this.remainingWork.put(resourceType, this.remainingWork.get(resourceType) - finishedWork); + this.remainingWork.put(resourceType, Math.max(0, this.remainingWork.get(resourceType) - finishedWork)); this.totalRemainingWork -= finishedWork; if (this.remainingWork.get(resourceType) <= 0) { this.workloadFinished.put(resourceType, true); @@ -173,7 +173,7 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { } // If this.totalRemainingWork <= 0, the fragment has been completed across all resources - if (this.totalRemainingWork <= 0 && !this.workloadFinished.containsValue(false)) { + if ((int) this.totalRemainingWork <= 0 && !this.workloadFinished.containsValue(false)) { this.startNextFragment(); this.invalidate(); @@ -203,9 +203,11 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { this.resourcesSupplied.get(resourceType), this.remainingWork.get(resourceType)); - if (remainingDuration == 0.0) { + if ((int) remainingDuration == 0) { // if resource not initialized, then nothing happens - this.totalRemainingWork -= this.remainingWork.get(resourceType); + if (this.remainingWork.get(resourceType) >= 0.0) { + this.totalRemainingWork -= this.remainingWork.get(resourceType); + } this.remainingWork.put(resourceType, 0.0); this.workloadFinished.put(resourceType, true); } @@ -218,7 +220,14 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { } } - return timeUntilNextUpdate == Long.MIN_VALUE ? now : now + timeUntilNextUpdate; + long nextUpdate = timeUntilNextUpdate == Long.MAX_VALUE ? Long.MAX_VALUE : now + timeUntilNextUpdate; + + // if for all resources the remaining work is 0, then invalidate the workload, to reschedule the next fragment + if (nextUpdate == now + Long.MIN_VALUE) { + this.invalidate(); + return Long.MAX_VALUE; + } + return nextUpdate; } public TraceFragment getNextFragment() { @@ -380,6 +389,10 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { */ @Override public void handleIncomingSupply(FlowEdge supplierEdge, double newSupply, ResourceType resourceType) { + // for cases where equal share or fixed share is used and the resource is provided despite not being used + if (!this.usedResourceTypes.contains(resourceType)) { + return; + } if (this.resourcesSupplied.get(resourceType) == newSupply) { return; } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowDistributor.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowDistributor.java index 501bbf10..5cfd16ba 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowDistributor.java +++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/FlowDistributor.java @@ -60,6 +60,7 @@ public abstract class FlowDistributor extends FlowNode implements FlowSupplier, protected Double totalIncomingSupply = 0.0; // The total supply provided by the suppliers protected boolean outgoingDemandUpdateNeeded = false; + protected boolean outgoingSupplyUpdateNeeded = false; protected Set<Integer> updatedDemands = new HashSet<>(); // Array of consumers that updated their demand in this cycle @@ -142,6 +143,9 @@ public abstract class FlowDistributor extends FlowNode implements FlowSupplier, } this.totalIncomingDemand -= consumerEdge.getDemand(); + if (this.totalIncomingDemand < 0) { + this.totalIncomingDemand = 0.0; + } // Remove idx from consumers that updated their demands this.updatedDemands.remove(idx); @@ -204,6 +208,9 @@ public abstract class FlowDistributor extends FlowNode implements FlowSupplier, incomingDemands.set(idx, newDemand); // only update the total supply if the new supply is different from the previous one this.totalIncomingDemand += (newDemand - prevDemand); + if (totalIncomingDemand < 0) { + this.totalIncomingDemand = 0.0; + } this.updatedDemands.add(idx); @@ -230,6 +237,7 @@ public abstract class FlowDistributor extends FlowNode implements FlowSupplier, // only update the total supply if the new supply is different from the previous one this.totalIncomingSupply += (newSupply - prevSupply); + this.outgoingSupplyUpdateNeeded = true; this.invalidate(); } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/BestEffortFlowDistributor.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/BestEffortFlowDistributor.java index 4a13beb2..703aca35 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/BestEffortFlowDistributor.java +++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/BestEffortFlowDistributor.java @@ -148,6 +148,7 @@ public class BestEffortFlowDistributor extends FlowDistributor { } } + this.outgoingSupplyUpdateNeeded = false; this.updatedDemands.clear(); } @@ -264,7 +265,7 @@ public class BestEffortFlowDistributor extends FlowDistributor { } // Update supplies if needed - if (!this.outgoingSupplies.isEmpty() || updateNeeded) { + if (this.outgoingSupplyUpdateNeeded || updateNeeded) { this.updateOutgoingSupplies(); } diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/EqualShareFlowDistributor.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/EqualShareFlowDistributor.java index f58164cf..87ed7ca2 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/EqualShareFlowDistributor.java +++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/EqualShareFlowDistributor.java @@ -54,6 +54,8 @@ public class EqualShareFlowDistributor extends FlowDistributor { } this.outgoingDemandUpdateNeeded = false; + this.updatedDemands.clear(); + this.invalidate(); } /** diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FirstFitPolicyFlowDistributor.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FirstFitPolicyFlowDistributor.java index c0a8cd13..9ab24d9f 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FirstFitPolicyFlowDistributor.java +++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FirstFitPolicyFlowDistributor.java @@ -74,6 +74,7 @@ public class FirstFitPolicyFlowDistributor extends FlowDistributor { } this.outgoingDemandUpdateNeeded = false; + this.invalidate(); } /** diff --git a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FixedShareFlowDistributor.java b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FixedShareFlowDistributor.java index 4c0a84d1..f22ea9fb 100644 --- a/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FixedShareFlowDistributor.java +++ b/opendc-simulator/opendc-simulator-flow/src/main/java/org/opendc/simulator/engine/graph/distributionPolicies/FixedShareFlowDistributor.java @@ -112,9 +112,6 @@ public class FixedShareFlowDistributor extends FlowDistributor { } else { double[] supplies = distributeSupply(this.incomingDemands, this.outgoingSupplies, this.totalIncomingSupply); for (FlowEdge consumerEdge : this.consumerEdges) { - if (supplies[consumerIndex] <= 0.0) { - continue; - } this.pushOutgoingSupply(consumerEdge, this.fixedShare); } } @@ -123,7 +120,8 @@ public class FixedShareFlowDistributor extends FlowDistributor { public double[] distributeSupply(ArrayList<Double> demands, ArrayList<Double> currentSupply, double totalSupply) { double[] supplies = new double[this.consumerEdges.size()]; - if (this.consumerEdges.size() < this.supplierEdges.size()) { + if (this.consumerEdges.size() < this.supplierEdges.size() + && this.fixedShare * this.consumerEdges.size() <= totalSupply) { for (FlowEdge consumerEdge : this.consumerEdges) { supplies[consumerEdge.getConsumerIndex()] = this.fixedShare; } |
