/** * Remaps the entire Vm's {@link UtilizationHistory} by updating the CPU utilization value in each entry * to correspond to the percentage of the Host CPU capacity that Vm is using. * * @param utilizationHistory the VM {@link UtilizationHistory} with the history entries * @return */ private SortedMap<Double, Double> remapUtilizationHistory(final UtilizationHistory utilizationHistory) { return utilizationHistory .getHistory() .entrySet() .stream() .collect( toMap(Entry::getKey, vmUtilizationMapper(utilizationHistory), this::mergeFunction, TreeMap::new) ); }
/** * Receives a Vm {@link UtilizationHistory} and returns a {@link Function} that * requires a map entry from the history (representing a VM's CPU utilization for a given time), * and returns the percentage of the Host CPU capacity that Vm is using at that time. * This way, the value that represents how much of the VM's CPU is being used * will be converted to how much that VM is using from the Host's CPU. * * @param utilizationHistory the VM {@link UtilizationHistory} with the history entries * @return */ private Function<Entry<Double, Double>, Double> vmUtilizationMapper(final UtilizationHistory utilizationHistory) { final double totalMipsCapacity = getTotalMipsCapacity(); return entry -> entry.getValue() * utilizationHistory.getVm().getTotalMipsCapacity() / totalMipsCapacity; }
private List<Vm> createVms() { final List<Vm> list = new ArrayList<>(VMS); for (int i = 0; i < VMS; i++) { final Vm vm = new VmSimple(i, 1000, VM_PES); vm.setRam(512).setBw(1000).setSize(10000); vm.setCloudletScheduler(new CloudletSchedulerTimeShared()); vm.getUtilizationHistory().enable(); list.add(vm); } return list; }
@Override public double updateProcessing(final double currentTime, final List<Double> mipsShare) { requireNonNull(mipsShare); if(!cloudletScheduler.getCloudletExecList().isEmpty()){ this.lastBusyTime = getSimulation().clock(); } final double nextEventDelay = cloudletScheduler.updateProcessing(currentTime, mipsShare); notifyOnUpdateProcessingListeners(); /* If the current time is some value with the decimals greater than x.0 * (such as 45.1) and the next event delay is any integer number such as 5, * then the next simulation time will be 50.1. * At time 50.1 the utilization will be reduced due to the completion of the Cloudlet. * At time 50.0 the Cloudlet is still running, so there is some CPU utilization. * But since the next update will be only at time 50.1, the utilization * at time 50.0 won't be collected to enable knowing the exact time * before the utilization dropped. */ final double decimals = currentTime - (int) currentTime; utilizationHistory.addUtilizationHistory(currentTime); return nextEventDelay - decimals; }
/** * Creates a list of VMs. */ private List<Vm> createVms() { final List<Vm> list = new ArrayList<>(VMS); for (int i = 0; i < VMS; i++) { Vm vm = new VmSimple(i, 1000, VM_PES); vm.setRam(512).setBw(1000).setSize(10000) .setCloudletScheduler(new CloudletSchedulerTimeShared()); vm.getUtilizationHistory().enable(); list.add(vm); } return list; }
private void showCpuUtilizationForAllVms(final double simulationFinishTime) { System.out.println("\nHosts CPU utilization history for the entire simulation period\n"); int numberOfUsageHistoryEntries = 0; for (Vm vm : vmlist) { System.out.printf("VM %d\n", vm.getId()); if (vm.getUtilizationHistory().getHistory().isEmpty()) { System.out.println("\tThere isn't any usage history"); continue; } for (Map.Entry<Double, Double> entry : vm.getUtilizationHistory().getHistory().entrySet()) { final double time = entry.getKey(); final double vmCpuUsage = entry.getValue()*100; if (vmCpuUsage > 0) { numberOfUsageHistoryEntries++; System.out.printf("\tTime: %2.0f CPU Utilization: %6.2f%%\n", time, vmCpuUsage); } } } if (numberOfUsageHistoryEntries == 0) { System.out.println("No CPU usage history was found"); } }
public Vm createVm(DatacenterBroker broker, int pes) { Vm vm = new VmSimple(VM_MIPS, pes); vm .setRam(VM_RAM).setBw((long)VM_BW).setSize(VM_SIZE) .setCloudletScheduler(new CloudletSchedulerTimeShared()); vm.getUtilizationHistory().enable(); return vm; }
/** * Defines a dynamic CPU utilization threshold that indicates a Vm is overloaded. * Such a threshold is the maximum CPU a VM can use before requesting vertical CPU scaling. * A reference to this method is assigned to each Vertical VM Scaling created. * * <p>The dynamic upper threshold is defined as 20% above the mean (mean * 1.2), * if there are at least 10 CPU utilization history entries. * That means if the CPU utilization of a VM is 20% above its mean * CPU utilization, it indicates the VM is overloaded. * If there aren't enough history entries, * it defines a static threshold as 70% of CPU utilization.</p> * * @param vm the VM to check if its CPU is overloaded. * The parameter is not being used internally, that means the same * threshold is used for any Vm. * @return the upper dynamic CPU utilization threshold * @see #createVerticalPeScaling() */ private double upperCpuUtilizationThreshold(Vm vm) { final List<Double> history = vm.getUtilizationHistory().getHistory().values().stream().collect(Collectors.toList()); return history.size() > 10 ? MathUtil.median(history) * 1.2 : 0.7; }
/** * Creates a Vm object, enabling it to store * CPU utilization history which is used * to compute a dynamic threshold for CPU vertical scaling. * * @return the created Vm */ private Vm createVm() { final int id = createsVms++; final Vm vm = new VmSimple(id, 1000, VM_PES) .setRam(VM_RAM).setBw(1000).setSize(10000) .setCloudletScheduler(new CloudletSchedulerTimeShared()); vm.getUtilizationHistory().enable(); return vm; }
/** * Gets the CPU utilization percentage matrix for a given list of VMs. * * @param vmList the VM list * @return the CPU utilization percentage matrix, where each line i * is a VM and each column j is a CPU utilization percentage history for that VM. */ protected double[][] getUtilizationMatrix(final List<Vm> vmList) { final int numberVms = vmList.size(); final int minHistorySize = getMinUtilizationHistorySize(vmList); final double[][] utilization = new double[numberVms][minHistorySize]; for (int i = 0; i < numberVms; i++) { final double[] vmUtilization = vmList.get(i).getUtilizationHistory().getHistory().values().stream().mapToDouble(v -> v).toArray(); if (minHistorySize >= 0) { System.arraycopy(vmUtilization, 0, utilization[i], 0, minHistorySize); } } return utilization; }
/** * Creates a VM enabling the collection of CPU utilization history. * This way, hosts can get the CPU utilization based on VM utilization. * @param pesNumber * @param mips * @return */ private Vm createVm(final int pesNumber, final long mips) { final long size = 10000; //image size (Megabyte) final int ram = 2048; //vm memory (Megabyte) final long bw = 1000; Vm vm = new VmSimple(mips, pesNumber) .setRam(ram).setBw(bw).setSize(size) .setCloudletScheduler(new CloudletSchedulerTimeShared()); vm.getUtilizationHistory().enable(); return vm; }
/** * Shows updates every time the simulation clock advances. * @param evt information about the event happened (that for this Listener is just the simulation time) */ private void onClockTickListener(EventInfo evt) { vmList.forEach(vm -> { System.out.printf( "\t\tTime %6.1f: Vm %d CPU Usage: %6.2f%% (%2d vCPUs. Running Cloudlets: #%02d) Upper Threshold: %.2f History Entries: %d\n", evt.getTime(), vm.getId(), vm.getCpuPercentUsage()*100.0, vm.getNumberOfPes(), vm.getCloudletScheduler().getCloudletExecList().size(), vm.getPeVerticalScaling().getUpperThresholdFunction().apply(vm), vm.getUtilizationHistory().getHistory().size()); }); }
/** * Creates a VM enabling the collection of CPU utilization history. * @param pesNumber * @param mips * @param id * @return */ private Vm createVm(final int pesNumber, final int mips, final int id) { final long size = 10000; //image size (Megabyte) final int ram = 2048; //vm memory (Megabyte) final long bw = 1000; //create two VMs Vm vm = new VmSimple(id, mips, pesNumber); vm.setRam(ram).setBw(bw) .setSize(size) .setCloudletScheduler(new CloudletSchedulerTimeShared()); vm.getUtilizationHistory().enable();; return vm; }