Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save manoelcampos/78a8dd1b595ef5ceb0b89fa978661225 to your computer and use it in GitHub Desktop.
Save manoelcampos/78a8dd1b595ef5ceb0b89fa978661225 to your computer and use it in GitHub Desktop.
Examples comparing CloudSim and CloudSim Plus simulation frameworks
import org.cloudbus.cloudsim.Cloudlet;
import org.cloudbus.cloudsim.CloudletSchedulerTimeShared;
import org.cloudbus.cloudsim.Datacenter;
import org.cloudbus.cloudsim.DatacenterBroker;
import org.cloudbus.cloudsim.DatacenterCharacteristics;
import org.cloudbus.cloudsim.Host;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.Pe;
import org.cloudbus.cloudsim.UtilizationModel;
import org.cloudbus.cloudsim.UtilizationModelFull;
import org.cloudbus.cloudsim.Vm;
import org.cloudbus.cloudsim.VmAllocationPolicySimple;
import org.cloudbus.cloudsim.VmScheduler;
import org.cloudbus.cloudsim.VmSchedulerTimeShared;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.provisioners.BwProvisioner;
import org.cloudbus.cloudsim.provisioners.BwProvisionerSimple;
import org.cloudbus.cloudsim.provisioners.PeProvisionerSimple;
import org.cloudbus.cloudsim.provisioners.RamProvisioner;
import org.cloudbus.cloudsim.provisioners.RamProvisionerSimple;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
/**
* A CloudSim example for side-by-side comparison with CloudSim Plus.
* http://cloudsimplus.org/docs/CloudSim-and-CloudSimPlus-Comparison.html
*/
public class CloudSimExampleToCompareWithCloudSimPlus {
/** {@link Datacenter} scheduling interval.*/
private static final int SCHEDULING_INTERVAL = 10;
private static final int HOSTS = 2;
private static final int HOST_PES = 8;
private static final int VMS = 4;
private static final int VM_PES = 4;
private static final int CLOUDLETS = 8;
private static final int CLOUDLET_PES = 2;
private static final int CLOUDLET_LENGTH = 10000;
/* You don't instantiate a simulation instance
* and have to deal with static methods that
* makes it hard to extend. Furthermore, you aren't able
* to isolate multiple simulations scenarios. */
private final DatacenterBroker broker0;
private final List<Vm> vmList;
private final List<Cloudlet> cloudletList;
private final Datacenter datacenter0;
public static void main(String[] args){
new CloudSimExampleToCompareWithCloudSimPlus();
}
public CloudSimExampleToCompareWithCloudSimPlus() {
/*You just have pretty limited log capabilities. */
/* You have to call the static init method passing
* lots of weird parameters, some of them
* are never used (such as the first one).*/
CloudSim.init(1, Calendar.getInstance(), true);
datacenter0 = createDatacenter();
/* Simple tasks as creating a broker may throw an
exception that you have to deal with. */
try {
broker0 = new DatacenterBroker("broker1");
} catch (Exception e) {
throw new RuntimeException("Error creating broker: " + e.getMessage());
}
vmList = createVms();
cloudletList = createCloudlets();
broker0.submitVmList(vmList);
broker0.submitCloudletList(cloudletList);
/* CloudSim class represents the simulation.
startSimulation is a redundant method name. */
CloudSim.startSimulation();
/* Even startSimulation() being a blocking operation,
you have to call stopSimulation(). If you forget it,
you wont get proper simulation results.*/
CloudSim.stopSimulation();
/* You have to write your own method to iterate
over a cloudlet list and print results.
You don't have any built-in data export
feature. */
printCloudletList(broker0.getCloudletReceivedList());
}
private Datacenter createDatacenter() {
final List<Host> hostList = new ArrayList<>(HOSTS);
for(int i = 0; i < HOSTS; i++) {
Host host = createHost();
hostList.add(host);
}
/* You have to create a DatacenterCharacteristics objects
passing lots of parameters you probably will never use. */
DatacenterCharacteristics characteristics =
new DatacenterCharacteristics("x86", "Linux", "Xen",
hostList, 0, 0, 0, 0, 0);
/* Once again, you have to deal with exceptions
just to create an object
*/
try {
/* The constructor requires lots
of parameters,
being confusing.*/
return new Datacenter(
"dc1", characteristics, new VmAllocationPolicySimple(hostList),
new ArrayList<>(), SCHEDULING_INTERVAL);
} catch (Exception e) {
throw new RuntimeException("Error creating Datacenter", e);
}
}
private Host createHost() {
final List<Pe> peList = new ArrayList<>(HOST_PES);
for (int i = 0; i < HOST_PES; i++) {
/* To create a Pe (CPU) you have to provide
a PeProvisioner,
even though there is
only one implementation by default. */
peList.add(new Pe(i, new PeProvisionerSimple(1000)));
}
final int ram = 2048; //in Megabytes
final long bw = 10000; //in Megabits/s
final long storage = 1000000; //in Megabytes
final RamProvisioner ramProvisioner = new RamProvisionerSimple(ram);
final BwProvisioner bwProvisioner = new BwProvisionerSimple(bw);
final VmScheduler vmScheduler = new VmSchedulerTimeShared(peList);
return new Host(
0, ramProvisioner, bwProvisioner, storage,
peList, vmScheduler);
}
private List<Vm> createVms() {
final List<Vm> vmList = new ArrayList<>(VMS);
for (int i = 0; i < VMS; i++) {
/*
You have to pass IDs instead of objects for lots
of methods, such as passing the broker ID here,
which is very error-prone.
Passing ID's around is one cause of many
issues on the simulator and makes it very difficult
and slow to find relationships between entities
(such as which Host is running a
VM and which Datacenter it belongs to).
The VM constructor is confusing,
having a huge number of parameters,
some that you don't even use.*/
Vm vm = new Vm(i, broker0.getId(), 1000, VM_PES,
1000, 10, 100,
"xen", new CloudletSchedulerTimeShared());
vmList.add(vm);
}
return vmList;
}
private List<Cloudlet> createCloudlets() {
final List<Cloudlet> cloudletList = new ArrayList<>(CLOUDLETS);
/*
UtilizationModelFull is not realistic
(no app uses 100% of resources all the time).
Despite of that, you just have Random and PlanetLab
implementations.
*/
UtilizationModel utilization = new UtilizationModelFull();
for (int i = 0; i < CLOUDLETS; i++) {
/* Cloudlet constructor is also very confusing.
There are again some parameters you
normally don't care but you have to provide.
You have to link the cloudlet to its broker
using the broker ID, which is error-prone.
If you forget it, you wont get proper
simulation results. Once again, we have useless
parameters, such as the last one.*/
Cloudlet cloudlet =
new Cloudlet(i, CLOUDLET_LENGTH, CLOUDLET_PES, 100, 100,
utilization, utilization, utilization, false);
cloudlet.setUserId(broker0.getId());
cloudletList.add(cloudlet);
}
return cloudletList;
}
private static void printCloudletList(List<Cloudlet> list) {
int size = list.size();
Cloudlet cloudlet;
String indent = " ";
Log.printLine();
Log.printLine("========== OUTPUT ==========");
Log.printLine("Cloudlet ID" + indent + "STATUS" + indent
+ "Data center ID" + indent + "VM ID" + indent + "Time" + indent
+ "Start Time" + indent + "Finish Time");
DecimalFormat dft = new DecimalFormat("###.##");
for (int i = 0; i < size; i++) {
cloudlet = list.get(i);
Log.print(indent + cloudlet.getCloudletId() + indent + indent);
if (cloudlet.getCloudletStatus() == Cloudlet.SUCCESS) {
Log.print("SUCCESS");
Log.printLine(indent + indent + cloudlet.getResourceId()
+ indent + indent + indent + cloudlet.getVmId()
+ indent + indent
+ dft.format(cloudlet.getActualCPUTime()) + indent
+ indent + dft.format(cloudlet.getStartTime())
+ indent + indent
+ dft.format(cloudlet.getFinishTime()));
}
}
}
}
import org.cloudsimplus.brokers.DatacenterBroker;
import org.cloudsimplus.brokers.DatacenterBrokerSimple;
import org.cloudsimplus.cloudlets.Cloudlet;
import org.cloudsimplus.cloudlets.CloudletSimple;
import org.cloudsimplus.core.CloudSimPlus;
import org.cloudsimplus.datacenters.Datacenter;
import org.cloudsimplus.datacenters.DatacenterSimple;
import org.cloudsimplus.hosts.Host;
import org.cloudsimplus.hosts.HostSimple;
import org.cloudsimplus.resources.Pe;
import org.cloudsimplus.resources.PeSimple;
import org.cloudsimplus.utilizationmodels.UtilizationModelDynamic;
import org.cloudsimplus.vms.Vm;
import org.cloudsimplus.vms.VmSimple;
import org.cloudsimplus.builders.tables.CloudletsTableBuilder;
import org.cloudsimplus.util.Log;
import java.util.ArrayList;
import java.util.List;
/**
* A CloudSim Plus example for side-by-side comparison with CloudSim.
* http://cloudsimplus.org/docs/CloudSim-and-CloudSimPlus-Comparison.html
*/
public class CloudSimPlusExampleToCompareWithCloudSim {
/* It's not required to set a scheduling interval.
* If one is not set, the default value is used. */
private static final int HOSTS = 2;
private static final int HOST_PES = 8;
private static final int VMS = 4;
private static final int VM_PES = 4;
private static final int CLOUDLETS = 8;
private static final int CLOUDLET_PES = 2;
private static final int CLOUDLET_LENGTH = 10000;
/** You have to create a simulation instance.
* This way, you can even run multiple simulations
* in parallel. */
private final CloudSimPlus simulation;
private final DatacenterBroker broker0;
private final List<Vm> vmList;
private final List<Cloudlet> cloudletList;
private final Datacenter datacenter0;
public static void main(String[] args) {
new CloudSimPlusExampleToCompareWithCloudSim();
}
private CloudSimPlusExampleToCompareWithCloudSim() {
/* We have LogBack as the logging framework
that enables advanced logging features such as
emitting just some level of log messages.
You can even control individual type of entities. */
Log.setLevel(ch.qos.logback.classic.Level.WARN);
/* You just calls the no-args constructor to
* init your simulation. As simple as that.*/
simulation = new CloudSimPlus();
datacenter0 = createDatacenter();
//To create a broker, you just call the constructor and that is it.
broker0 = new DatacenterBrokerSimple(simulation);
vmList = createVms();
cloudletList = createCloudlets();
broker0.submitVmList(vmList);
broker0.submitCloudletList(cloudletList);
/* No redundancy in method names.
Just call start(). */
simulation.start();
/*You dont' need to stop the simulation.
* It's stopped automatically after the
* start() call returns. */
/* You don't need to implement a method to print
simulation results. You can just use the the available builder.
It even enables you to customize the results
and export data in formats such as csv.*/
final List<Cloudlet> finishedCloudlets = broker0.getCloudletFinishedList();
new CloudletsTableBuilder(finishedCloudlets).build();
}
private Datacenter createDatacenter() {
final var hostList = new ArrayList<Host>(HOSTS);
for(int i = 0; i < HOSTS; i++) {
Host host = createHost();
hostList.add(host);
}
/* You don't need to explicitly create a
DatacenterCharacteristics object,
a default one will be created to you,
so that you just change the attributes you want.
*/
/* You don't have to deal with any weird
exception when creating a Datacenter.
The constructor just works.
*/
/* The constructor is much simpler.
If you don't pass a VmAllocationPolicy,
a VmAllocationPolicySimple is used by default. */
return new DatacenterSimple(simulation, hostList);
}
private Host createHost() {
final var peList = new ArrayList<Pe>(HOST_PES);
for (int i = 0; i < HOST_PES; i++) {
/* When creating a PE, if you don't provide a PeProvisioner,
a PeProvisionerSimple is used by default.
And you don't even bother with an PE id,
it's set automatically. */
peList.add(new PeSimple(1000));
}
final long ram = 2048; //in Megabytes
final long bw = 10000; //in Megabits/s
final long storage = 1000000; //in Megabytes
/* You don't need to create resource provisioners neither
a VmScheduler if you want to use
the default ResourceProvisionerSimple for RAM and BW provisioning
and VmSchedulerSpaceShared for VM scheduling.
This makes straightforward to call the constructor.
If you don't want to manage Host ID's, let the
simulation take care of them to you.
*/
return new HostSimple(ram, bw, storage, peList);
}
private List<Vm> createVms() {
final var vmList = new ArrayList<Vm>(VMS);
for (int i = 0; i < VMS; i++) {
/*
You don't even have to pass a broker when creating
a VM, because it will be linked to the broker
object (not it's ID) when you submit the VM.
Forget that confusing constructor,
it's a breezy to create a VM.
And if you just want to use a CloudletSchedulerTimeShared,
a new instance is provided for the VM by default.
If you don't want to set specific values for
RAM, BW and Storage capacity, the default ones
will be used. And you can even change these defaults.
*/
final Vm vm = new VmSimple(1000, VM_PES);
vm.setRam(512).setBw(1000).setSize(10000);
vmList.add(vm);
}
return vmList;
}
private List<Cloudlet> createCloudlets() {
final var cloudletList = new ArrayList<Cloudlet>(CLOUDLETS);
/* You have the flexible UtilizationModelDynamic
that enables customizing how a Cloudlet uses resources.
Here it's defining the Cloudlets use
only 50% of any resource all the time
(but this is just for example purposes).
But if you want, the UtilizationModelFull is still available.*/
final var utilizationModel = new UtilizationModelDynamic(0.5);
for (int i = 0; i < CLOUDLETS; i++) {
/* Here the constructor is much simpler. You can use
setters to customize some attributes latter on.
Cloudlet ID is even automatically generated
if you don't provide one. If you are using the
same UtilizationModel for CPU, RAM and BW,
you just have to pass it as parameter once.
Nevermind linking the cloudlet to its broker.
That is made for you when you submit the cloudlet.*/
final var cloudlet = new CloudletSimple(CLOUDLET_LENGTH, CLOUDLET_PES, utilizationModel);
cloudlet.setSizes(1024);
cloudletList.add(cloudlet);
}
return cloudletList;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment