diff options
Diffstat (limited to 'opendc-simulator/opendc-simulator-compute/src')
3 files changed, 174 insertions, 149 deletions
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 e56e1b5c..8c14943f 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 @@ -61,10 +61,11 @@ public class SimMachine { private SimPsu psu; private Memory memory; - private final Hashtable<ResourceType, FlowDistributor> distributors = new Hashtable<>(); + private final FlowDistributor[] distributors = new FlowDistributor[ResourceType.values().length]; + // private final Hashtable<ResourceType, FlowDistributor> distributors = new Hashtable<>(); + private final List<ResourceType> availableResourceTypes; private final Hashtable<ResourceType, ArrayList<ComputeResource>> computeResources = new Hashtable<>(); - private final List<ResourceType> availableResources; private final Consumer<Exception> completion; @@ -184,8 +185,8 @@ public class SimMachine { return 0.0; } - public List<ResourceType> getAvailableResources() { - return availableResources; + public List<ResourceType> getAvailableResourceTypes() { + return availableResourceTypes; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -203,13 +204,13 @@ public class SimMachine { this.machineModel = machineModel; this.clock = engine.getClock(); - this.availableResources = this.machineModel.getUsedResources(); + this.availableResourceTypes = this.machineModel.getUsedResources(); // 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.distributors[ResourceType.POWER.ordinal()] = new MaxMinFairnessFlowDistributor(engine); // Maybe First fit + new FlowEdge(this.distributors[ResourceType.POWER.ordinal()], this.psu); this.computeResources.put( ResourceType.CPU, @@ -218,17 +219,16 @@ public class SimMachine { // Connect the CPU to the PSU new FlowEdge( (FlowConsumer) this.computeResources.get(ResourceType.CPU).getFirst(), - (FlowSupplier) this.distributors.get(ResourceType.POWER), + (FlowSupplier) this.distributors[ResourceType.POWER.ordinal()], ResourceType.POWER, 0, -1); // Create a FlowDistributor and add the cpu as supplier - this.distributors.put( - ResourceType.CPU, - FlowDistributorFactory.getFlowDistributor(engine, this.machineModel.getCpuDistributionStrategy())); + this.distributors[ResourceType.CPU.ordinal()] = + FlowDistributorFactory.getFlowDistributor(engine, this.machineModel.getCpuDistributionStrategy()); new FlowEdge( - this.distributors.get(ResourceType.CPU), + this.distributors[ResourceType.CPU.ordinal()], (FlowSupplier) this.computeResources.get(ResourceType.CPU).getFirst(), ResourceType.CPU, -1, @@ -237,10 +237,9 @@ public class SimMachine { // TODO: include memory as flow node this.memory = new Memory(engine, this.machineModel.getMemory()); - if (this.availableResources.contains(ResourceType.GPU)) { - this.distributors.put( - ResourceType.GPU, - FlowDistributorFactory.getFlowDistributor(engine, this.machineModel.getGpuDistributionStrategy())); + if (this.availableResourceTypes.contains(ResourceType.GPU)) { + this.distributors[ResourceType.GPU.ordinal()] = + FlowDistributorFactory.getFlowDistributor(engine, this.machineModel.getGpuDistributionStrategy()); ArrayList<ComputeResource> gpus = new ArrayList<>(); for (GpuModel gpuModel : machineModel.getGpuModels()) { @@ -250,7 +249,7 @@ public class SimMachine { gpus.add(gpu); // Connect the GPU to the distributor new FlowEdge( - this.distributors.get(ResourceType.GPU), + this.distributors[ResourceType.GPU.ordinal()], gpu, ResourceType.GPU, gpuModel.getId(), @@ -258,7 +257,7 @@ public class SimMachine { // Connect the GPU to the PSU new FlowEdge( gpu, - this.distributors.get(ResourceType.POWER), + this.distributors[ResourceType.POWER.ordinal()], ResourceType.POWER, gpuModel.getId(), gpuModel.getId()); @@ -289,10 +288,10 @@ public class SimMachine { } this.memory = null; - for (ResourceType resourceType : this.distributors.keySet()) { - this.distributors.get(resourceType).closeNode(); + for (ResourceType resourceType : this.availableResourceTypes) { + this.distributors[resourceType.ordinal()].closeNode(); + this.distributors[resourceType.ordinal()] = null; } - this.distributors.clear(); this.completion.accept(cause); } @@ -319,8 +318,8 @@ public class SimMachine { public VirtualMachine startWorkload(ChainWorkload workload, Consumer<Exception> completion) { ArrayList<FlowSupplier> distributors = new ArrayList<>(); - for (ResourceType resourceType : this.availableResources) { - distributors.add(this.distributors.get(resourceType)); + for (ResourceType resourceType : this.availableResourceTypes) { + distributors.add(this.distributors[resourceType.ordinal()]); } return (VirtualMachine) workload.startWorkload(distributors, this, completion); diff --git a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/VirtualMachine.java b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/VirtualMachine.java index a8944efe..a3ee4f97 100644 --- a/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/VirtualMachine.java +++ b/opendc-simulator/opendc-simulator-compute/src/main/java/org/opendc/simulator/compute/workload/VirtualMachine.java @@ -23,7 +23,7 @@ package org.opendc.simulator.compute.workload; import java.util.ArrayList; -import java.util.Hashtable; +import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -51,12 +51,23 @@ public final class VirtualMachine extends SimWorkload implements FlowSupplier { private FlowEdge workloadEdge; - private final Hashtable<ResourceType, Double> resourceDemands = new Hashtable<>(); - private final Hashtable<ResourceType, Double> resourceSupplies = new Hashtable<>(); - private final Hashtable<ResourceType, Double> resourceCapacities = new Hashtable<>(); - private final Hashtable<ResourceType, Double> resourceTimeScalingFactor = new Hashtable<>(); // formerly known as d - private final Hashtable<ResourceType, FlowEdge> distributorEdges = new Hashtable<>(); - private final Hashtable<ResourceType, PerformanceCounters> resourcePerformanceCounters = new Hashtable<>(); + private final List<ResourceType> usedResourceTypes = new ArrayList<>(); + + private final double[] resourceDemands = new double[ResourceType.values().length]; + private final double[] resourceSupplies = new double[ResourceType.values().length]; + private final double[] resourceCapacities = new double[ResourceType.values().length]; + private final double[] resourceTimeScalingFactor = new double[ResourceType.values().length]; // formerly known as d + private final FlowEdge[] distributorEdges = new FlowEdge[ResourceType.values().length]; + private final PerformanceCounters[] resourcePerformanceCounters = + new PerformanceCounters[ResourceType.values().length]; + + // private final Hashtable<ResourceType, Double> resourceDemands = new Hashtable<>(); + // private final Hashtable<ResourceType, Double> resourceSupplies = new Hashtable<>(); + // private final Hashtable<ResourceType, Double> resourceCapacities = new Hashtable<>(); + // private final Hashtable<ResourceType, Double> resourceTimeScalingFactor = new Hashtable<>(); // formerly known + // as d + // private final Hashtable<ResourceType, FlowEdge> distributorEdges = new Hashtable<>(); + // private final Hashtable<ResourceType, PerformanceCounters> resourcePerformanceCounters = new Hashtable<>(); private final long checkpointInterval; private final long checkpointDuration; @@ -68,8 +79,6 @@ public final class VirtualMachine extends SimWorkload implements FlowSupplier { private long lastUpdate; private Consumer<Exception> completion; - private final List<ResourceType> availableResources = new ArrayList<>(); - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Basic Getters and Setters //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -84,7 +93,7 @@ public final class VirtualMachine extends SimWorkload implements FlowSupplier { if (resourceType == ResourceType.AUXILIARY) { return 0.0; } - return this.resourceCapacities.get(resourceType); + return this.resourceCapacities[resourceType.ordinal()]; } @Override @@ -108,11 +117,11 @@ public final class VirtualMachine extends SimWorkload implements FlowSupplier { } public PerformanceCounters getCpuPerformanceCounters() { - return this.resourcePerformanceCounters.get(ResourceType.CPU); + return this.resourcePerformanceCounters[ResourceType.CPU.ordinal()]; } public PerformanceCounters getGpuPerformanceCounters() { - return this.resourcePerformanceCounters.get(ResourceType.GPU); + return this.resourcePerformanceCounters[ResourceType.GPU.ordinal()]; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -138,7 +147,7 @@ public final class VirtualMachine extends SimWorkload implements FlowSupplier { } this.workloadIndex = -1; - this.availableResources.add(supplier.getSupplierResourceType()); + this.usedResourceTypes.add(supplier.getSupplierResourceType()); this.onStart(); } @@ -152,20 +161,21 @@ public final class VirtualMachine extends SimWorkload implements FlowSupplier { new FlowEdge(this, supplier); ResourceType resourceType = supplier.getSupplierResourceType(); - this.availableResources.add(resourceType); + this.usedResourceTypes.add(resourceType); ArrayList<ComputeResource> resources = machine.getResources(resourceType); if (resources.isEmpty()) { throw new IllegalArgumentException("No resources of type " + resourceType + " found in machine "); } - this.resourceCapacities.put(resourceType, resources.getFirst().getCapacity()); + this.resourceCapacities[resourceType.ordinal()] = + resources.getFirst().getCapacity(); - this.resourceTimeScalingFactor.put( - resourceType, 1.0 / resources.getFirst().getCapacity()); - this.resourcePerformanceCounters.put(resourceType, new PerformanceCounters()); - this.resourceDemands.put(resourceType, 0.0); - this.resourceSupplies.put(resourceType, 0.0); + this.resourceTimeScalingFactor[resourceType.ordinal()] = + 1.0 / resources.getFirst().getCapacity(); + this.resourcePerformanceCounters[resourceType.ordinal()] = new PerformanceCounters(); + this.resourceDemands[resourceType.ordinal()] = 0.0; + this.resourceSupplies[resourceType.ordinal()] = 0.0; } this.workloads = new LinkedList<>(workload.workloads()); @@ -208,26 +218,25 @@ public final class VirtualMachine extends SimWorkload implements FlowSupplier { this.lastUpdate = now; long delta = now - lastUpdate; - for (ResourceType resourceType : this.availableResources) { - final double factor = this.resourceTimeScalingFactor.get(resourceType) * delta; + for (ResourceType resourceType : this.usedResourceTypes) { + final double factor = this.resourceTimeScalingFactor[resourceType.ordinal()] * delta; if (delta > 0) { - this.resourcePerformanceCounters - .get(resourceType) - .addActiveTime(Math.round(this.resourceSupplies.get(resourceType) * factor)); - this.resourcePerformanceCounters - .get(resourceType) - .setIdleTime(Math.round( - (this.resourceCapacities.get(resourceType) - this.resourceSupplies.get(resourceType)) - * factor)); - this.resourcePerformanceCounters - .get(resourceType) - .addStealTime(Math.round( - (this.resourceDemands.get(resourceType) - this.resourceSupplies.get(resourceType)) - * factor)); + this.resourcePerformanceCounters[resourceType.ordinal()].addActiveTime( + Math.round(this.resourceSupplies[resourceType.ordinal()] * factor)); + this.resourcePerformanceCounters[resourceType.ordinal()].setIdleTime( + Math.round((this.resourceCapacities[resourceType.ordinal()] + - this.resourceSupplies[resourceType.ordinal()]) + * factor)); + this.resourcePerformanceCounters[resourceType.ordinal()].addStealTime(Math.round( + (this.resourceDemands[resourceType.ordinal()] - this.resourceSupplies[resourceType.ordinal()]) + * factor)); } - this.resourcePerformanceCounters.get(resourceType).setDemand(this.resourceDemands.get(resourceType)); - this.resourcePerformanceCounters.get(resourceType).setSupply(this.resourceSupplies.get(resourceType)); - this.resourcePerformanceCounters.get(resourceType).setCapacity(this.resourceCapacities.get(resourceType)); + this.resourcePerformanceCounters[resourceType.ordinal()].setDemand( + this.resourceDemands[resourceType.ordinal()]); + this.resourcePerformanceCounters[resourceType.ordinal()].setSupply( + this.resourceSupplies[resourceType.ordinal()]); + this.resourcePerformanceCounters[resourceType.ordinal()].setCapacity( + this.resourceCapacities[resourceType.ordinal()]); } } @@ -305,13 +314,8 @@ public final class VirtualMachine extends SimWorkload implements FlowSupplier { @Override public void addSupplierEdge(FlowEdge supplierEdge) { ResourceType resourceType = supplierEdge.getSupplierResourceType(); - if (this.resourceCapacities.containsKey(resourceType) && this.resourceCapacities.get(resourceType) > 0) { - this.resourceCapacities.put( - resourceType, this.resourceCapacities.get(resourceType) + supplierEdge.getCapacity()); - } else { - this.resourceCapacities.put(resourceType, supplierEdge.getCapacity()); - } - this.distributorEdges.put(resourceType, supplierEdge); + this.resourceCapacities[resourceType.ordinal()] = supplierEdge.getCapacity(); + this.distributorEdges[resourceType.ordinal()] = supplierEdge; } /** @@ -335,8 +339,8 @@ public final class VirtualMachine extends SimWorkload implements FlowSupplier { @Override public void pushOutgoingDemand(FlowEdge supplierEdge, double newDemand, ResourceType resourceType) { // FIXME: Needs to be assigned to specific resource if multiple exist -> add resource Id as parameter - this.resourceDemands.put(resourceType, newDemand); - this.distributorEdges.get(resourceType).pushDemand(newDemand, false, resourceType); + this.resourceDemands[resourceType.ordinal()] = newDemand; + this.distributorEdges[resourceType.ordinal()].pushDemand(newDemand, false, resourceType); } /** @@ -347,10 +351,9 @@ public final class VirtualMachine extends SimWorkload implements FlowSupplier { */ @Override public void pushOutgoingSupply(FlowEdge consumerEdge, double newSupply) { - this.resourceSupplies.put(consumerEdge.getConsumerResourceType(), newSupply); - this.distributorEdges - .get(consumerEdge.getConsumerResourceType()) - .pushSupply(newSupply, false, consumerEdge.getConsumerResourceType()); + this.resourceSupplies[consumerEdge.getConsumerResourceType().ordinal()] = newSupply; + this.distributorEdges[consumerEdge.getConsumerResourceType().ordinal()].pushSupply( + newSupply, false, consumerEdge.getConsumerResourceType()); } /** @@ -361,7 +364,7 @@ public final class VirtualMachine extends SimWorkload implements FlowSupplier { */ @Override public void pushOutgoingSupply(FlowEdge consumerEdge, double newSupply, ResourceType resourceType) { - this.resourceSupplies.put(resourceType, newSupply); + this.resourceSupplies[resourceType.ordinal()] = newSupply; this.workloadEdge.pushSupply(newSupply, false, resourceType); } @@ -374,13 +377,14 @@ public final class VirtualMachine extends SimWorkload implements FlowSupplier { @Override public void handleIncomingDemand(FlowEdge consumerEdge, double newDemand) { updateCounters(this.clock.millis()); - this.pushOutgoingDemand(this.distributorEdges.get(consumerEdge.getConsumerResourceType()), newDemand); + this.pushOutgoingDemand( + this.distributorEdges[consumerEdge.getConsumerResourceType().ordinal()], newDemand); } @Override public void handleIncomingDemand(FlowEdge consumerEdge, double newDemand, ResourceType resourceType) { updateCounters(this.clock.millis()); - this.pushOutgoingDemand(this.distributorEdges.get(resourceType), newDemand, resourceType); + this.pushOutgoingDemand(this.distributorEdges[resourceType.ordinal()], newDemand, resourceType); } /** @@ -394,7 +398,7 @@ public final class VirtualMachine extends SimWorkload implements FlowSupplier { updateCounters(this.clock.millis()); this.pushOutgoingSupply( - this.distributorEdges.get(supplierEdge.getSupplierResourceType()), + this.distributorEdges[supplierEdge.getSupplierResourceType().ordinal()], newSupply, supplierEdge.getSupplierResourceType()); } @@ -409,7 +413,7 @@ public final class VirtualMachine extends SimWorkload implements FlowSupplier { public void handleIncomingSupply(FlowEdge supplierEdge, double newSupply, ResourceType resourceType) { updateCounters(this.clock.millis()); - this.pushOutgoingSupply(this.distributorEdges.get(resourceType), newSupply, resourceType); + this.pushOutgoingSupply(this.distributorEdges[resourceType.ordinal()], newSupply, resourceType); } /** @@ -446,7 +450,7 @@ public final class VirtualMachine extends SimWorkload implements FlowSupplier { */ @Override public void removeSupplierEdge(FlowEdge supplierEdge) { - if (!this.distributorEdges.contains(supplierEdge.getSupplierResourceType())) { + if (this.distributorEdges[supplierEdge.getSupplierResourceType().ordinal()] == null) { return; } @@ -456,7 +460,7 @@ public final class VirtualMachine extends SimWorkload implements FlowSupplier { @Override public Map<FlowEdge.NodeType, List<FlowEdge>> getConnectedEdges() { List<FlowEdge> consumerEdges = - this.distributorEdges.values().stream().filter(Objects::nonNull).toList(); + Arrays.stream(this.distributorEdges).filter(Objects::nonNull).toList(); List<FlowEdge> supplierEdges = (this.workloadEdge != null) ? List.of(this.workloadEdge) : List.of(); return Map.of( @@ -464,7 +468,7 @@ public final class VirtualMachine extends SimWorkload implements FlowSupplier { FlowEdge.NodeType.SUPPLYING, supplierEdges); } - public List<ResourceType> getAvailableResources() { - return this.availableResources; + public List<ResourceType> getUsedResourceTypes() { + return this.usedResourceTypes; } } 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 39e17819..c91f94d4 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 @@ -46,21 +46,23 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { private TraceFragment currentFragment; private long startOfFragment; - private final Map<ResourceType, FlowEdge> machineResourceEdges = new HashMap<>(); + private final FlowEdge[] machineResourceEdges = new FlowEdge[ResourceType.values().length]; // TODO: Currently GPU memory is not considered and can not be used private final ArrayList<ResourceType> usedResourceTypes = new ArrayList<>(); - private final Map<ResourceType, Double> resourcesSupplied = new HashMap<>(); // the currently supplied resources - private final Map<ResourceType, Double> newResourcesSupply = - new HashMap<>(); // The supplied resources with next update - private final Map<ResourceType, Double> resourcesDemand = new HashMap<>(); // The demands per resource type - private final Map<ResourceType, Double> remainingWork = - new HashMap<>(); // The duration of the fragment at the demanded speeds + + private final double[] resourcesSupplied = + new double[ResourceType.values().length]; // the currently supplied resources + private final double[] newResourcesSupply = + new double[ResourceType.values().length]; // The supplied resources with next update + private final double[] resourcesDemand = new double[ResourceType.values().length]; // The demands per resource type + private final double[] remainingWork = + new double[ResourceType.values().length]; // The duration of the fragment at the demanded speeds private double totalRemainingWork = 0.0; // The total remaining work of the fragment across all resources, used to determine the end of the // fragment - private final Map<ResourceType, Boolean> workloadFinished = - new HashMap<>(); // The workload finished for each resource type + private final boolean[] workloadFinished = + new boolean[ResourceType.values().length]; // The workload finished for each resource type private final long checkpointDuration; private final TraceWorkload snapshot; @@ -116,11 +118,12 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { // instead iterate over the resources in the fragment as required resources not provided by the VM for (ResourceType resourceType : workload.getResourceTypes()) { this.usedResourceTypes.add(resourceType); - this.resourcesSupplied.put(resourceType, 0.0); - this.newResourcesSupply.put(resourceType, 0.0); - this.resourcesDemand.put(resourceType, 0.0); - this.remainingWork.put(resourceType, 0.0); - this.workloadFinished.put(resourceType, false); + + // this.resourcesSupplied.put(resourceType, 0.0); + // this.newResourcesSupply.put(resourceType, 0.0); + // this.resourcesDemand.put(resourceType, 0.0); + // this.remainingWork.put(resourceType, 0.0); + // this.workloadFinished.put(resourceType, false); } } } @@ -143,11 +146,11 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { if (supplier.getSupplierResourceType() != ResourceType.AUXILIARY) { new FlowEdge(this, supplier); this.usedResourceTypes.add(supplier.getSupplierResourceType()); - this.resourcesSupplied.put(supplier.getSupplierResourceType(), 0.0); - this.newResourcesSupply.put(supplier.getSupplierResourceType(), 0.0); - this.resourcesDemand.put(supplier.getSupplierResourceType(), 0.0); - this.remainingWork.put(supplier.getSupplierResourceType(), 0.0); - this.workloadFinished.put(supplier.getSupplierResourceType(), false); + // this.resourcesSupplied.put(supplier.getSupplierResourceType(), 0.0); + // this.newResourcesSupply.put(supplier.getSupplierResourceType(), 0.0); + // this.resourcesDemand.put(supplier.getSupplierResourceType(), 0.0); + // this.remainingWork.put(supplier.getSupplierResourceType(), 0.0); + // this.workloadFinished.put(supplier.getSupplierResourceType(), false); } } } @@ -156,6 +159,15 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { // Fragment related functionality //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + public boolean isWorkloadFinished() { + for (ResourceType resourceType : this.usedResourceTypes) { + if (!this.workloadFinished[resourceType.ordinal()]) { + return false; + } + } + return true; + } + @Override public long onUpdate(long now) { long passedTime = getPassedTime(now); @@ -164,16 +176,21 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { for (ResourceType resourceType : this.usedResourceTypes) { // 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, Math.max(0, this.remainingWork.get(resourceType) - finishedWork)); + this.resourcesDemand[resourceType.ordinal()], + this.resourcesSupplied[resourceType.ordinal()], + passedTime); + + // TODO: maybe remove Math.max, as as we are already checking for <= 0 + this.remainingWork[resourceType.ordinal()] = + Math.max(0, this.remainingWork[resourceType.ordinal()] - finishedWork); this.totalRemainingWork -= finishedWork; - if (this.remainingWork.get(resourceType) <= 0) { - this.workloadFinished.put(resourceType, true); + if (this.remainingWork[resourceType.ordinal()] <= 0) { + this.workloadFinished[resourceType.ordinal()] = true; } } // If this.totalRemainingWork <= 0, the fragment has been completed across all resources - if ((int) this.totalRemainingWork <= 0 && !this.workloadFinished.containsValue(false)) { + if ((int) this.totalRemainingWork <= 0 && this.isWorkloadFinished()) { this.startNextFragment(); this.invalidate(); @@ -181,17 +198,17 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { } for (ResourceType resourceType : this.usedResourceTypes) { - if (this.machineResourceEdges.get(resourceType) != null) { + if (this.machineResourceEdges[resourceType.ordinal()] != null) { this.pushOutgoingDemand( - this.machineResourceEdges.get(resourceType), - this.resourcesDemand.get(resourceType), + this.machineResourceEdges[resourceType.ordinal()], + this.resourcesDemand[resourceType.ordinal()], resourceType); } } // Update the supplied resources for (ResourceType resourceType : this.usedResourceTypes) { - this.resourcesSupplied.put(resourceType, this.newResourcesSupply.get(resourceType)); + this.resourcesSupplied[resourceType.ordinal()] = this.newResourcesSupply[resourceType.ordinal()]; } long timeUntilNextUpdate = Long.MIN_VALUE; @@ -199,17 +216,17 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { for (ResourceType resourceType : this.usedResourceTypes) { // The amount of time required to finish the fragment at this speed long remainingDuration = this.scalingPolicy.getRemainingDuration( - this.resourcesDemand.get(resourceType), - this.resourcesSupplied.get(resourceType), - this.remainingWork.get(resourceType)); + this.resourcesDemand[resourceType.ordinal()], + this.resourcesSupplied[resourceType.ordinal()], + this.remainingWork[resourceType.ordinal()]); if ((int) remainingDuration == 0) { // if resource not initialized, then nothing happens - if (this.remainingWork.get(resourceType) >= 0.0) { - this.totalRemainingWork -= this.remainingWork.get(resourceType); + if (this.remainingWork[resourceType.ordinal()] >= 0.0) { + this.totalRemainingWork -= this.remainingWork[resourceType.ordinal()]; } - this.remainingWork.put(resourceType, 0.0); - this.workloadFinished.put(resourceType, true); + this.remainingWork[resourceType.ordinal()] = 0.0; + this.workloadFinished[resourceType.ordinal()] = true; } // The next update should happen when the fastest resource is done, so that it is no longer tracked when @@ -255,12 +272,13 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { for (ResourceType resourceType : usedResourceTypes) { double demand = nextFragment.getResourceUsage(resourceType); - this.remainingWork.put(resourceType, this.scalingPolicy.getRemainingWork(demand, nextFragment.duration())); - this.totalRemainingWork += this.remainingWork.get(resourceType); - this.workloadFinished.put(resourceType, false); + this.remainingWork[resourceType.ordinal()] = + this.scalingPolicy.getRemainingWork(demand, nextFragment.duration()); + this.totalRemainingWork += this.remainingWork[resourceType.ordinal()]; + this.workloadFinished[resourceType.ordinal()] = false; - if (this.machineResourceEdges.get(resourceType) != null) { - this.pushOutgoingDemand(this.machineResourceEdges.get(resourceType), demand, resourceType); + if (this.machineResourceEdges[resourceType.ordinal()] != null) { + this.pushOutgoingDemand(this.machineResourceEdges[resourceType.ordinal()], demand, resourceType); } } } @@ -276,8 +294,8 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { this.closeNode(); for (ResourceType resourceType : this.usedResourceTypes) { - this.machineResourceEdges.put(resourceType, null); - this.workloadFinished.put(resourceType, true); + this.machineResourceEdges[resourceType.ordinal()] = null; + this.workloadFinished[resourceType.ordinal()] = true; } this.remainingFragments = null; this.currentFragment = null; @@ -308,8 +326,10 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { // The amount of work done since last update for (ResourceType resourceType : this.usedResourceTypes) { double finishedWork = this.scalingPolicy.getFinishedWork( - this.resourcesDemand.get(resourceType), this.resourcesSupplied.get(resourceType), passedTime); - this.remainingWork.put(resourceType, this.remainingWork.get(resourceType) - finishedWork); + this.resourcesDemand[resourceType.ordinal()], + this.resourcesSupplied[resourceType.ordinal()], + passedTime); + this.remainingWork[resourceType.ordinal()] = this.remainingWork[resourceType.ordinal()] - finishedWork; this.totalRemainingWork -= finishedWork; } @@ -320,9 +340,9 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { remainingDuration = Math.max( remainingDuration, this.scalingPolicy.getRemainingDuration( - this.resourcesDemand.get(resourceType), - this.resourcesSupplied.get(resourceType), - this.remainingWork.get(resourceType))); + this.resourcesDemand[resourceType.ordinal()], + this.resourcesSupplied[resourceType.ordinal()], + this.remainingWork[resourceType.ordinal()])); } // If this is the end of the Task, don't make a snapshot @@ -372,11 +392,12 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { @Override public void handleIncomingSupply(FlowEdge supplierEdge, double newSupply) { ResourceType suppliedResourceType = ResourceType.CPU; - if (this.resourcesSupplied.get(suppliedResourceType) == newSupply) { + if (this.resourcesSupplied[suppliedResourceType.ordinal()] == newSupply) { return; } - this.resourcesSupplied.put(suppliedResourceType, this.newResourcesSupply.get(suppliedResourceType)); - this.newResourcesSupply.put(suppliedResourceType, newSupply); + this.resourcesSupplied[suppliedResourceType.ordinal()] = + this.newResourcesSupply[suppliedResourceType.ordinal()]; + this.newResourcesSupply[suppliedResourceType.ordinal()] = newSupply; this.invalidate(); } @@ -393,11 +414,11 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { if (!this.usedResourceTypes.contains(resourceType)) { return; } - if (this.resourcesSupplied.get(resourceType) == newSupply) { + if (this.resourcesSupplied[resourceType.ordinal()] == newSupply) { return; } - this.resourcesSupplied.put(resourceType, this.newResourcesSupply.get(resourceType)); - this.newResourcesSupply.put(resourceType, newSupply); + this.resourcesSupplied[resourceType.ordinal()] = this.newResourcesSupply[resourceType.ordinal()]; + this.newResourcesSupply[resourceType.ordinal()] = newSupply; this.invalidate(); } @@ -411,12 +432,12 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { @Override public void pushOutgoingDemand(FlowEdge supplierEdge, double newDemand) { ResourceType demandedResourceType = ResourceType.CPU; - if (this.resourcesDemand.get(demandedResourceType) == newDemand) { + if (this.resourcesDemand[demandedResourceType.ordinal()] == newDemand) { return; } - this.resourcesDemand.put(demandedResourceType, newDemand); - this.machineResourceEdges.get(demandedResourceType).pushDemand(newDemand); + this.resourcesDemand[demandedResourceType.ordinal()] = newDemand; + this.machineResourceEdges[demandedResourceType.ordinal()].pushDemand(newDemand); } /** * Push a new demand to the Virtual Machine @@ -426,12 +447,12 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { */ @Override public void pushOutgoingDemand(FlowEdge supplierEdge, double newDemand, ResourceType resourceType) { - if (this.resourcesDemand.get(resourceType) == newDemand) { + if (this.resourcesDemand[resourceType.ordinal()] == newDemand) { return; } - this.resourcesDemand.put(resourceType, newDemand); - this.machineResourceEdges.get(resourceType).pushDemand(newDemand, false, resourceType); + this.resourcesDemand[resourceType.ordinal()] = newDemand; + this.machineResourceEdges[resourceType.ordinal()].pushDemand(newDemand, false, resourceType); } /** @@ -443,18 +464,18 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { public void addSupplierEdge(FlowEdge supplierEdge) { ResourceType incommingResourceType = supplierEdge.getResourceType(); - if (machineResourceEdges.containsValue(supplierEdge)) { + if (machineResourceEdges[incommingResourceType.ordinal()] == (supplierEdge)) { return; // Skip if this exact edge is already registered } - this.machineResourceEdges.put(incommingResourceType, supplierEdge); + this.machineResourceEdges[incommingResourceType.ordinal()] = supplierEdge; if (supplierEdge.getSupplier() instanceof VirtualMachine vm) { - for (ResourceType resourceType : vm.getAvailableResources()) { + for (ResourceType resourceType : vm.getUsedResourceTypes()) { if (resourceType == incommingResourceType || resourceType == ResourceType.AUXILIARY) { continue; } - if (!this.machineResourceEdges.containsKey(resourceType)) { + if (this.machineResourceEdges[resourceType.ordinal()] == null) { new FlowEdge(this, vm, resourceType); } } @@ -480,8 +501,9 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { public Map<FlowEdge.NodeType, List<FlowEdge>> getConnectedEdges() { Map<FlowEdge.NodeType, List<FlowEdge>> connectedEdges = new HashMap<>(); for (ResourceType resourceType : ResourceType.values()) { - if (this.machineResourceEdges.get(resourceType) != null) { - connectedEdges.put(FlowEdge.NodeType.CONSUMING, List.of(this.machineResourceEdges.get(resourceType))); + if (this.machineResourceEdges[resourceType.ordinal()] != null) { + connectedEdges.put( + FlowEdge.NodeType.CONSUMING, List.of(this.machineResourceEdges[resourceType.ordinal()])); } } return connectedEdges; @@ -491,7 +513,7 @@ public class SimTraceWorkload extends SimWorkload implements FlowConsumer { // Util Methods //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private boolean areAllEdgesNull() { - for (FlowEdge edge : this.machineResourceEdges.values()) { + for (FlowEdge edge : this.machineResourceEdges) { if (edge != null) { return false; } |
