Skip to content

Commit

Permalink
- Finished the first version of the CloudletSchedulerCompletelyFair, …
Browse files Browse the repository at this point in the history
…the most used scheduler in recent versions of Linux Kernel.

- Included new testbeds in the cloudsim-plus-testbeds module to compare the new scheduler with the CloudletSchedulerTimeShared
- Included the LinuxCompletelyFairSchedulerExample example for the new scheduler in the cloudsim-plus-examples module
  • Loading branch information
manoelcampos committed Nov 9, 2016
1 parent cae9d35 commit d5768cd
Show file tree
Hide file tree
Showing 27 changed files with 1,113 additions and 497 deletions.
@@ -1,6 +1,5 @@
package org.cloudsimplus.examples;

import org.cloudsimplus.util.tablebuilder.CloudletsTableBuilderHelper;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.LinkedList;
Expand Down Expand Up @@ -32,14 +31,15 @@
import org.cloudbus.cloudsim.provisioners.ResourceProvisionerSimple;
import org.cloudbus.cloudsim.resources.Ram;
import org.cloudbus.cloudsim.schedulers.CloudletSchedulerCompletelyFair;
import org.cloudsimplus.util.tablebuilder.PriorityCloudletsTableBuilderHelper;

/**
* An example that uses an implementation of the {@link CloudletSchedulerCompletelyFair Completely Fair Scheduler}
* used in the Linux Kernel for scheduling of Cloudlets execution inside a Vm.
*
*
* @author Manoel Campos da Silva Filho
* @see <a href="https://en.wikipedia.org/wiki/Completely_Fair_Scheduler">Completely Fair Scheduler (CFS)</a>
*
*
*/
public class LinuxCompletelyFairSchedulerExample {
private static final int HOSTS_NUMBER = 1;
Expand All @@ -51,21 +51,21 @@ public class LinuxCompletelyFairSchedulerExample {
private static final int CLOUDLETS_NUMBER = HOST_PES*2;
private static final int CLOUDLET_PES = 1;
private static final int CLOUDLET_LEN = 10000; //in MI

/**
* Virtual Machine Monitor name.
*/
private static final String VMM = "Xen";
private static final String VMM = "Xen";
private List<Cloudlet> cloudletList;
private List<Vm> vmList;

private int numberOfCreatedCloudlets = 0;
private int numberOfCreatedVms = 0;
private int numberOfCreatedHosts = 0;

/**
* Starts the simulation.
* @param args
* @param args
*/
public static void main(String[] args) {
new LinuxCompletelyFairSchedulerExample();
Expand All @@ -78,9 +78,9 @@ public LinuxCompletelyFairSchedulerExample() {
Log.printFormattedLine("Starting %s...", getClass().getSimpleName());
try {
//Number of cloud customers
int numberOfCloudUsers = 1;
int numberOfCloudUsers = 1;
boolean traceEvents = false;

CloudSim.init(numberOfCloudUsers, Calendar.getInstance(), traceEvents);

Datacenter datacenter0 = createDatacenter("Datacenter0");
Expand All @@ -90,12 +90,12 @@ public LinuxCompletelyFairSchedulerExample() {
createAndSubmitVms(broker0);
createAndSubmitCloudlets(broker0);
for(int i = 0; i < CLOUDLETS_NUMBER/2; i++){
cloudletList.get(i).setPriority(10);
cloudletList.get(i).setPriority(4);
}

CloudSim.startSimulation();
CloudSim.stopSimulation();

List<Cloudlet> finishedCloudlets = broker0.getCloudletsFinishedList();
new PriorityCloudletsTableBuilderHelper(finishedCloudlets).build();
Log.printFormattedLine("%s finished!", getClass().getSimpleName());
Expand All @@ -117,13 +117,13 @@ private void createAndSubmitVms(DatacenterBroker broker0) {
for(int i = 0; i < VMS_NUMBER; i++){
this.vmList.add(createVm(broker0));
}
broker0.submitVmList(vmList);
broker0.submitVmList(vmList);
}

private DatacenterSimple createDatacenter(String name) {
List<Host> hostList = new ArrayList<>(HOSTS_NUMBER);
for(int i = 0; i < HOSTS_NUMBER; i++){
hostList.add(createHost());
hostList.add(createHost());
}

//Defines the characteristics of the data center
Expand All @@ -140,17 +140,17 @@ private DatacenterSimple createDatacenter(String name) {
arch, os, VMM, hostList, time_zone, cost, costPerMem,
costPerStorage, costPerBw);

return new DatacenterSimple(name, characteristics,
return new DatacenterSimple(name, characteristics,
new VmAllocationPolicySimple(hostList), storageList, 0);
}
}

private Host createHost() {
final int ram = 2048; // host memory (MB)
final long storage = 1000000; // host storage
final long bw = 10000;

List<Pe> cpuCoresList = createHostPesList(HOST_MIPS);

return new HostSimple(numberOfCreatedHosts++,
new ResourceProvisionerSimple<>(new Ram(ram)),
new ResourceProvisionerSimple<>(new Bandwidth(bw)),
Expand All @@ -163,59 +163,36 @@ private List<Pe> createHostPesList(double mips) {
for(int i = 0; i < HOST_PES; i++){
cpuCoresList.add(new PeSimple(i, new PeProvisionerSimple(mips)));
}

return cpuCoresList;
}

private Vm createVm(DatacenterBroker broker) {
final long storage = 10000; // vm image size (MB)
final int ram = 512; // vm memory (MB)
final long bw = 1000; // vm bandwidth
return new VmSimple(numberOfCreatedVms++,
broker.getId(), VM_MIPS, VM_PES, ram, bw, storage,
VMM, new CloudletSchedulerCompletelyFair());
final long bw = 1000; // vm bandwidth

return new VmSimple(numberOfCreatedVms++,
broker.getId(), VM_MIPS, VM_PES, ram, bw, storage, VMM,
new CloudletSchedulerCompletelyFair());
}

private Cloudlet createCloudlet(DatacenterBroker broker) {
final long fileSize = 300; //Size (in bytes) before execution
final long outputSize = 300; //Size (in bytes) after execution

//Defines how CPU, RAM and Bandwidth resources are used
//Sets the same utilization model for all these resources.
UtilizationModel utilization = new UtilizationModelFull();

Cloudlet cloudlet
= new CloudletSimple(
numberOfCreatedCloudlets++, CLOUDLET_LEN, CLOUDLET_PES,
fileSize, outputSize,
numberOfCreatedCloudlets++, CLOUDLET_LEN, CLOUDLET_PES,
fileSize, outputSize,
utilization, utilization, utilization);
cloudlet.setUserId(broker.getId());

return cloudlet;
}
}

/**
* A helper class to print cloudlets results as a table that includes
* the Cloudlet priority as a table field.
*
* @author Manoel Campos da Silva Filho
*/
class PriorityCloudletsTableBuilderHelper extends CloudletsTableBuilderHelper {
public PriorityCloudletsTableBuilderHelper(List<? extends Cloudlet> list) {
super(list);
}

@Override
protected void createTableColumns() {
super.createTableColumns();
getPrinter().addColumn("Priority");
}

@Override
protected void addDataToRow(Cloudlet cloudlet, List<Object> row) {
super.addDataToRow(cloudlet, row);
row.add(cloudlet.getPriority());
}
}
Expand Up @@ -11,7 +11,9 @@

/**
* A base class to run a given experiment a defined number of times
* and collect statistics about the execution.
* and collect statistics about the execution. The runner represents a testbed
* compounded of a set of experiments that it runs.
*
* @param <T> the class of experiment the runner will execute
* @author Manoel Campos da Silva Filho
*/
Expand Down Expand Up @@ -324,33 +326,40 @@ public long getBaseSeed() {
/**
* Gets the seeds used to run each experiment.
*
* @see #createRandomGen(int)
* @see #createRandomGenAndAddSeedToList(int, double, double)
*/
public List<Long> getSeeds() {
return seeds;
}

/**
* Creates a pseudo random number generator (PRNG) for a experiment run.
* If it is to apply the {@link #isApplyAntitheticVariatesTechnique() "Antithetic Variates Technique"} to reduce
* Creates a pseudo random number generator (PRNG) for a experiment run that generates
* uniform values between [min and max[. Adds the PRNG seed to the {@link #getSeeds()} list.
* If it is to apply the {@link #isApplyAntitheticVariatesTechnique() "Antithetic Variates Technique"} to reduce
* results variance, the second half of experiments will used
* the seeds from the first half.
*
* @param minValue the minimum value that generator will return (inclusive)
* @param maxValue the minimum value that generator will return (exclusive)
* @return the created PRNG
*
* @see UniformDistr#isApplyAntitheticVariatesTechnique()
*/
protected UniformDistr createRandomGen(int experimentIndex) {
if (isApplyAntitheticVariatesTechnique() && experimentIndex >= halfSimulationRuns()) {
protected UniformDistr createRandomGenAndAddSeedToList(int experimentIndex, double minValue, double maxValue) {
UniformDistr prng;
if (isApplyAntitheticVariatesTechnique() &&
numberOfSimulationRuns > 1 && experimentIndex >= halfSimulationRuns()) {
int previousExperiment = experimentIndex - halfSimulationRuns();

return new UniformDistr(0, 1, seeds.get(previousExperiment))
prng = new UniformDistr(minValue, maxValue, seeds.get(previousExperiment))
.setApplyAntitheticVariatesTechnique(true);
}

final long experimentSeed = getBaseSeed() + experimentIndex + 1;
return new UniformDistr(0, 1, experimentSeed);
}
prng = new UniformDistr(minValue, maxValue, experimentSeed);
addSeed(prng.getSeed());
return prng;
}

/**
* Adds a seed to the list of seeds used for each experiment.
Expand Down Expand Up @@ -390,19 +399,23 @@ public void run() {
setupInternal();

printSimulationParameters();
Log.disable();

experimentsStartTime = System.currentTimeMillis();
for(int i = 0; i < getNumberOfSimulationRuns(); i++){
if(isVerbose()) {
System.out.print(((i+1) % 100 == 0 ? String.format(". Run #%d\n", i+1) : "."));
}
createExperiment(i).run();
}
System.out.println();
experimentsFinishTime = (System.currentTimeMillis() - experimentsStartTime)/1000;

printResults(computeStatistics());
Log.disable();
try {
experimentsStartTime = System.currentTimeMillis();
for(int i = 0; i < getNumberOfSimulationRuns(); i++){
if(isVerbose()) {
System.out.print(((i+1) % 100 == 0 ? String.format(". Run #%d\n", i+1) : "."));
}
createExperiment(i).run();
}
System.out.println();
experimentsFinishTime = (System.currentTimeMillis() - experimentsStartTime)/1000;
} finally {
Log.enable();
}

printFinalResults(computeFinalStatistics());
}

/**
Expand Down Expand Up @@ -431,7 +444,7 @@ public void run() {
* if the "Antithetic Variates Technique" is to be applied,
* otherwise return the same given samples list.
*
* @see #createRandomGen(int)
* @see #createRandomGenAndAddSeedToList(int, double, double)
*/
protected List<Double> computeAntitheticMeans(List<Double> samples) {
if(!isApplyAntitheticVariatesTechnique())
Expand All @@ -451,15 +464,22 @@ protected List<Double> computeAntitheticMeans(List<Double> samples) {
}

protected abstract void printSimulationParameters();
protected abstract SummaryStatistics computeStatistics();

/**
* Computes the final statistics for all experiment runs.
*
* @return
*/
protected abstract SummaryStatistics computeFinalStatistics();

/**
* Prints final simulation results such as means, standard deviations
* and confidence intervals.
*
* @param stats the {@link SummaryStatistics} object to compute the statistics
* @param stats the {@link SummaryStatistics} containing means of each experiment run
* that will be used to computed an overall mean and other statistics
*/
protected abstract void printResults(SummaryStatistics stats);
protected abstract void printFinalResults(SummaryStatistics stats);

public ExperimentRunner setBaseSeed(long baseSeed) {
this.baseSeed = baseSeed;
Expand All @@ -468,11 +488,19 @@ public ExperimentRunner setBaseSeed(long baseSeed) {

/**
* Indicates if the runner will output execution logs or not.
* This doesn't affect the verbosity of individual experiments executed.
* Each {@link SimulationExperiment} has its own verbose attribute.
*/
public boolean isVerbose() {
return verbose;
}

/**
* Defines if the runner will output execution logs or not.
* This doesn't affect the verbosity of individual experiments executed.
* Each {@link SimulationExperiment} has its own verbose attribute.
* @param verbose true if the results have to be output, falser otherwise
*/
public ExperimentRunner setVerbose(boolean verbose) {
this.verbose = verbose;
return this;
Expand Down

0 comments on commit d5768cd

Please sign in to comment.