Commit be756713 authored by Eduardo Falcão's avatar Eduardo Falcão
Browse files

Merge branch 'iops-cloudlet-resource' into 'development'

Merge branch 'iops-cloudlet-resource' into 'development'

See merge request lenovo-autonomic/cloudsimplus!9
parents 911da424 67480fad
......@@ -40,6 +40,7 @@ import org.cloudbus.cloudsim.provisioners.ResourceProvisioner;
import org.cloudbus.cloudsim.provisioners.ResourceProvisionerSimple;
import org.cloudbus.cloudsim.resources.Pe;
import org.cloudbus.cloudsim.resources.PeSimple;
import org.cloudbus.cloudsim.schedulers.cloudlet.CloudletSchedulerSpaceShared;
import org.cloudbus.cloudsim.schedulers.cloudlet.CloudletSchedulerTimeShared;
import org.cloudbus.cloudsim.schedulers.vm.VmScheduler;
import org.cloudbus.cloudsim.schedulers.vm.VmSchedulerTimeShared;
......@@ -70,9 +71,10 @@ public class BasicFirstExample {
private static final int VMS = 2;
private static final int VM_PES = 4;
private static final int CLOUDLETS = 4;
private static final int CLOUDLET_PES = 2;
private static final int CLOUDLETS = 2;
private static final int CLOUDLET_PES = 4;
private static final int CLOUDLET_LENGTH = 10000;
private static final int CLOUDLET_IOPS = 10000;
private final CloudSim simulation;
private DatacenterBroker broker0;
......@@ -144,9 +146,10 @@ public class BasicFirstExample {
final List<Vm> list = new ArrayList<>(VMS);
for (int i = 0; i < VMS; i++) {
Vm vm =
new VmSimple(i, 1000, VM_PES)
new VmSimple(i,1000, VM_PES)
.setRam(512).setBw(1000).setSize(10000)
.setCloudletScheduler(new CloudletSchedulerTimeShared());
.setCloudletScheduler(new CloudletSchedulerTimeShared())
.setIops(333);
list.add(vm);
}
......@@ -165,7 +168,8 @@ public class BasicFirstExample {
new CloudletSimple(i, CLOUDLET_LENGTH, CLOUDLET_PES)
.setFileSize(1024)
.setOutputSize(1024)
.setUtilizationModel(utilization);
.setUtilizationModel(utilization)
.setIops(CLOUDLET_IOPS);
list.add(cloudlet);
}
......
......@@ -466,6 +466,27 @@ public interface Cloudlet extends UniquelyIdentificable, Comparable<Cloudlet>, C
* @see #getUtilizationModelBw() ()
*/
double getUtilizationOfBw(double time);
/**
* Gets the utilization of Iops at the current simulation time, that is defined in
* percentage or absolute values, depending of the {@link UtilizationModel#getUnit()}
* set for the {@link #getUtilizationModelBw() BW utilizaton model}.
*
* @return the utilization value
* @see #getUtilizationModelCpu()
*/
double getUtilizationOfIops();
/**
* Gets the utilization of Iops at a given time, that is defined in
* percentage or absolute values, depending of the {@link UtilizationModel#getUnit()}
* defined for the {@link #getUtilizationModelBw()} ()}.
*
* @param time the time to get the utilization
* @return the utilization value
* @see #getUtilizationModelBw() ()
*/
double getUtilizationOfIops(double time);
/**
* Gets the id of Vm that is planned to execute the cloudlet.
......@@ -669,6 +690,15 @@ public interface Cloudlet extends UniquelyIdentificable, Comparable<Cloudlet>, C
* @see #getNumberOfPes()
*/
long getLength();
/**
* Gets the execution iops of this Cloudlet.
*
* @return the iops of this Cloudlet
* @pre $none
* @post $result >= 0.0
*/
long getIops();
/**
* Sets the execution length of this Cloudlet (in Million Instructions (MI))
......@@ -684,6 +714,19 @@ public interface Cloudlet extends UniquelyIdentificable, Comparable<Cloudlet>, C
* @post $none
*/
Cloudlet setLength(long length);
/**
* Sets the execution iops of this Cloudlet.
*
* @param iops of this Cloudlet to be executed in a Vm
* @return
* @throws IllegalArgumentException when the given length is lower or equal to zero
*
* @pre iops > 0
* @post $none
*/
Cloudlet setIops(long iops);
/**
* Gets the total length (across all PEs) of this Cloudlet (in MI). It considers the
......@@ -703,6 +746,15 @@ public interface Cloudlet extends UniquelyIdentificable, Comparable<Cloudlet>, C
* @post $result >= 0.0
*/
long getTotalLength();
/**
* Gets the total iops of this Cloudlet.
* @return the total iops of this cloudlet
*
* @pre $none
* @post $result >= 0.0
*/
long getTotalIops();
/**
* Gets the length of this Cloudlet that has been executed so far from the
......@@ -715,6 +767,19 @@ public interface Cloudlet extends UniquelyIdentificable, Comparable<Cloudlet>, C
* @post $result >= 0.0
*/
long getFinishedLengthSoFar();
/**
* Gets the iops of this Cloudlet that has been executed so far from the
* latest Datacenter (in MI). This method is useful when trying to move this
* Cloudlet into different Datacenter or to cancel it.
*
* @return the iops of a partially executed Cloudlet, or the full Cloudlet
* iops if it is completed
* @pre $none
* @post $result >= 0.0
*/
long getFinishedIopsSoFar();
/**
* Gets the length of this Cloudlet that has been executed so far (in MI),
......@@ -730,6 +795,21 @@ public interface Cloudlet extends UniquelyIdentificable, Comparable<Cloudlet>, C
* @post $result >= 0.0
*/
long getFinishedLengthSoFar(Datacenter datacenter);
/**
* Gets the iops of this Cloudlet that has been executed so far,
* according to the {@link #getIops()}.
* This method is useful when trying to move this Cloudlet
* into different Datacenters or to cancel it.
*
* @param datacenter the Datacenter entity
* @return the iops of a partially executed Cloudlet; the full Cloudlet
* iops if it is completed; or 0 if the Cloudlet has never been executed
* in the given Datacenter
* @pre resId >= 0
* @post $result >= 0.0
*/
long getFinishedIopsSoFar(Datacenter datacenter);
/**
* Sets the length of this Cloudlet that has been executed so far (in MI),
......@@ -743,6 +823,19 @@ public interface Cloudlet extends UniquelyIdentificable, Comparable<Cloudlet>, C
* @post $none
*/
boolean setFinishedLengthSoFar(long length);
/**
* Sets the iops of this Cloudlet that has been executed so far,
* according to the {@link #getIops()}.
*
* @param Iops executed length of this Cloudlet
* @return true if the iops is valid and the cloudlet already has assigned
* to a Datacenter, false otherwise
* @see CloudletExecution
* @pre length >= 0.0
* @post $none
*/
boolean setFinishedIopsSoFar(long length);
/**
* Sets the wall clock time the cloudlet spent
......
......@@ -11,6 +11,7 @@ import org.cloudbus.cloudsim.brokers.DatacenterBroker;
import org.cloudbus.cloudsim.core.Simulation;
import org.cloudbus.cloudsim.core.UniquelyIdentificable;
import org.cloudbus.cloudsim.datacenters.Datacenter;
import org.cloudbus.cloudsim.util.Log;
import org.cloudbus.cloudsim.utilizationmodels.UtilizationModel;
import org.cloudbus.cloudsim.vms.Vm;
import org.cloudsimplus.listeners.CloudletVmEventInfo;
......@@ -47,6 +48,10 @@ public abstract class CloudletAbstract implements Cloudlet {
* @see #getLength()
*/
private long length;
/**
* @see #getIops()
*/
private long iops;
/**
* @see #getNumberOfPes()
*/
......@@ -157,6 +162,7 @@ public abstract class CloudletAbstract implements Cloudlet {
setVm(Vm.NULL);
this.setLength(length);
this.setIops(1);
this.setFileSize(1);
this.setOutputSize(1);
......@@ -171,6 +177,51 @@ public abstract class CloudletAbstract implements Cloudlet {
onUpdateProcessingListeners = new HashSet<>();
}
/**
* Creates a Cloudlet with no priority and file size and output size equal to 1.
*
* @param cloudletId id of the Cloudlet
* @param length the length or size (in MI) of this cloudlet to be executed in a VM
* @param pesNumber number of PEs that Cloudlet will require
*/
public CloudletAbstract(final int cloudletId, final long length, final long iops, final long pesNumber) {
/*
Normally, a Cloudlet is only executed on a Datacenter without being
migrated to others. Hence, to reduce memory consumption, set the
size of this ArrayList to be less than the default one.
*/
this.datacenterExecutionList = new ArrayList<>(2);
this.requiredFiles = new LinkedList<>();
this.id = cloudletId;
this.netServiceLevel = 0;
this.execStartTime = 0.0;
this.status = Status.INSTANTIATED;
this.priority = 0;
this.setNumberOfPes(pesNumber);
this.lastExecutedDatacenterIdx = NOT_ASSIGNED;
setBroker(DatacenterBroker.NULL);
setFinishTime(NOT_ASSIGNED); // meaning this Cloudlet hasn't finished yet
setVm(Vm.NULL);
this.setLength(length);
this.setIops(iops);
this.setFileSize(1);
this.setOutputSize(1);
setAccumulatedBwCost(0.0);
setCostPerBw(0.0);
setSubmissionDelay(0.0);
setUtilizationModelCpu(UtilizationModel.NULL);
setUtilizationModelRam(UtilizationModel.NULL);
setUtilizationModelBw(UtilizationModel.NULL);
setUtilizationModelIops(UtilizationModel.NULL);
onFinishListeners = new HashSet<>();
onUpdateProcessingListeners = new HashSet<>();
}
/**
* Creates a Cloudlet with no priority or id. The id is defined when the Cloudlet is submitted to
* a {@link DatacenterBroker}. The file size and output size is defined as 1.
......@@ -206,6 +257,7 @@ public abstract class CloudletAbstract implements Cloudlet {
setUtilizationModelBw(utilizationModel);
setUtilizationModelRam(utilizationModel);
setUtilizationModelCpu(utilizationModel);
setUtilizationModelIops(utilizationModel);
return this;
}
......@@ -240,13 +292,23 @@ public abstract class CloudletAbstract implements Cloudlet {
@Override
public final Cloudlet setLength(final long length) {
if (length <= 0) {
if (length < 0) {
throw new IllegalArgumentException("Cloudlet length has to be greater than zero.");
}
this.length = length;
return this;
}
@Override
public final Cloudlet setIops(final long iops) {
if (iops < 0) {
throw new IllegalArgumentException("Cloudlet iops has to be greater than zero.");
}
this.iops = iops;
return this;
}
@Override
public boolean setNetServiceLevel(final int netServiceLevel) {
......@@ -302,6 +364,11 @@ public abstract class CloudletAbstract implements Cloudlet {
public long getFinishedLengthSoFar(final Datacenter datacenter) {
return getDatacenterInfo(datacenter).getFinishedSoFar();
}
@Override
public long getFinishedIopsSoFar(final Datacenter datacenter) {
return getDatacenterInfo(datacenter).getFinishedIopsSoFar();
}
@Override
public long getFinishedLengthSoFar() {
......@@ -311,14 +378,24 @@ public abstract class CloudletAbstract implements Cloudlet {
return Math.min(getLastExecutionInDatacenterInfo().getFinishedSoFar(), getLength());
}
@Override
public long getFinishedIopsSoFar() {
if (datacenterExecutionList.isEmpty()) {
return 0;
}
return Math.min(getLastExecutionInDatacenterInfo().getFinishedIopsSoFar(), getIops());
}
@Override
public boolean isFinished() {
public boolean isFinished() {
if (datacenterExecutionList.isEmpty()) {
return false;
}
return getLastExecutionInDatacenterInfo().getFinishedSoFar() >= getLength();
return getLastExecutionInDatacenterInfo().getFinishedSoFar() >= getLength() &&
getLastExecutionInDatacenterInfo().getFinishedIopsSoFar() >= getIops();
}
@Override
......@@ -331,6 +408,17 @@ public abstract class CloudletAbstract implements Cloudlet {
notifyListenersIfCloudletIsFinished();
return true;
}
@Override
public boolean setFinishedIopsSoFar(final long iops) {
if (iops < 0.0 || datacenterExecutionList.isEmpty()) {
return false;
}
getLastExecutionInDatacenterInfo().setFinishedIopsSoFar(Math.min(iops, this.getIops()));
notifyListenersIfCloudletIsFinished();
return true;
}
/**
* Notifies all registered listeners about the termination of the Cloudlet
......@@ -422,11 +510,21 @@ public abstract class CloudletAbstract implements Cloudlet {
public long getLength() {
return length;
}
@Override
public long getIops() {
return iops;
}
@Override
public long getTotalLength() {
return length * numberOfPes;
}
@Override
public long getTotalIops() {
return iops;
}
@Override
public double getCostPerSec() {
......@@ -689,6 +787,16 @@ public abstract class CloudletAbstract implements Cloudlet {
public double getUtilizationOfRam(final double time) {
return getUtilizationModelRam().getUtilization(time);
}
@Override
public double getUtilizationOfIops() {
return getUtilizationOfIops(getSimulation().clock());
}
@Override
public double getUtilizationOfIops(final double time) {
return getUtilizationModelIops().getUtilization(time);
}
@Override
public double getCostPerBw() {
......
......@@ -15,6 +15,7 @@ final class CloudletDatacenterExecution {
private double actualCpuTime;
private double costPerSec;
private long finishedSoFar;
private long finishedIopsSoFar;
private Datacenter datacenter;
CloudletDatacenterExecution() {
......@@ -74,10 +75,21 @@ final class CloudletDatacenterExecution {
long getFinishedSoFar() {
return finishedSoFar;
}
/*
* Cloudlet's iops finished so far
*/
long getFinishedIopsSoFar() {
return finishedIopsSoFar;
}
void setFinishedSoFar(long finishedSoFar) {
this.finishedSoFar = finishedSoFar;
}
void setFinishedIopsSoFar(long finishedIopsSoFar) {
this.finishedIopsSoFar = finishedIopsSoFar;
}
/**
* a Datacenter where the Cloudlet will be executed
......
......@@ -67,6 +67,14 @@ public class CloudletExecution {
* length of the cloudlet (not just the executed length in the current Datacenter).
*/
private long instructionsFinishedSoFar;
/**
* The iops of Cloudlet finished so far.
* The attribute stores the execution iops of the cloudlet
* in previous datacenters. Thus, it represents the actual executed
* iops of the cloudlet (not just the executed length in the current Datacenter).
*/
private long iopsFinishedSoFar;
/**
* Latest cloudlet execution start time in the current Datacenter.
......@@ -117,6 +125,7 @@ public class CloudletExecution {
//In case a Cloudlet has been executed partially by some other Host
this.instructionsFinishedSoFar = cloudlet.getFinishedLengthSoFar() * Conversion.MILLION;
this.iopsFinishedSoFar = cloudlet.getFinishedIopsSoFar();
}
/**
......@@ -129,6 +138,17 @@ public class CloudletExecution {
public long getCloudletLength() {
return cloudlet.getLength();
}
/**
* Gets the Cloudlet's iops.
*
* @return Cloudlet's iops
* @pre $none
* @post $none
*/
public long getCloudletIops() {
return cloudlet.getIops();
}
public long getNumberOfPes(){
return cloudlet.getNumberOfPes();
......@@ -213,6 +233,19 @@ public class CloudletExecution {
final double remainingMI = cloudlet.getLength() - (instructionsFinishedSoFar / (double)Conversion.MILLION);
return (remainingMI < 0 ? 0 : (long)remainingMI);
}
/**
* Gets the remaining cloudlet iops that has to be execute yet,
* considering the {@link Cloudlet#getIops()}.
*
* @return cloudlet iops
* @pre $none
* @post $result >= 0
*/
public long getRemainingCloudletIops() {
final double remainingIops = cloudlet.getIops() - iopsFinishedSoFar;
return (remainingIops < 0 ? 0 : (long)remainingIops);
}
/**
* Finalizes all relevant information before <tt>exiting</tt> the Datacenter
......@@ -237,8 +270,14 @@ public class CloudletExecution {
cloudlet.getStatus() == Cloudlet.Status.SUCCESS ?
cloudlet.getLength() :
instructionsFinishedSoFar / Conversion.MILLION;
final long finishedIops =
cloudlet.getStatus() == Cloudlet.Status.SUCCESS ?
cloudlet.getIops() :
iopsFinishedSoFar;
cloudlet.setFinishedLengthSoFar(finishedLength);
cloudlet.setFinishedIopsSoFar(finishedIops);
}
/**
......@@ -246,22 +285,37 @@ public class CloudletExecution {
*
* @param executedInstructions amount of instructions just executed, to be
* added to the {@link #instructionsFinishedSoFar}, in Instructions (instead of Million Instructions)
* @param executedIops amount of iops just executed, to be
* added to the {@link #iopsFinishedSoFar}
* @pre instructionsExecuted >= 0.0
* @post $none
*/
public void updateProcessing(final long executedInstructions) {
public void updateProcessing(final long executedInstructions, final long executedIops) {
setLastProcessingTime(cloudlet.getSimulation().clock());
if(executedInstructions <= 0){
return;
}
this.instructionsFinishedSoFar += executedInstructions;
this.instructionsFinishedSoFar =
Math.min(this.instructionsFinishedSoFar, cloudlet.getLength()*Conversion.MILLION);
final double finishedSoFarByPeMI = instructionsFinishedSoFar / Conversion.MILLION;
cloudlet.setFinishedLengthSoFar((long)finishedSoFarByPeMI);
final double finishedSoFarByPeMI = instructionsFinishedSoFar / Conversion.MILLION;
if(executedInstructions <= 0){
return;
} else {
cloudlet.setFinishedLengthSoFar((long)finishedSoFarByPeMI);
}
this.iopsFinishedSoFar += executedIops;
this.iopsFinishedSoFar =
Math.min(this.iopsFinishedSoFar, cloudlet.getIops());
final double finishedIopsSoFar = iopsFinishedSoFar;
if(executedIops <= 0){
return;
} else {
cloudlet.setFinishedIopsSoFar((long)finishedIopsSoFar);
}
}
/**
......
......@@ -238,5 +238,45 @@ final class CloudletNull implements Cloudlet {
@Override public double registerArrivalInDatacenter() {
return -1;
}
@Override
public double getUtilizationOfIops() {
// TODO Auto-generated method stub
return 0;
}
@Override
public double getUtilizationOfIops(double time) {
// TODO Auto-generated method stub
return 0;
}
@Override
public long getIops() {
// TODO Auto-generated method stub
return 0;
}
@Override
public Cloudlet setIops(long length) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getTotalIops() {
// TODO Auto-generated method stub
return 0;
}
@Override
public long getFinishedIopsSoFar() {
// TODO Auto-generated method stub
return 0;
}
@Override
public long getFinishedIopsSoFar(Datacenter datacenter) {
// TODO Auto-generated method stub
return 0;
}
@Override
public boolean setFinishedIopsSoFar(long length) {
// TODO Auto-generated method stub
return false;
}
}
......@@ -9,6 +9,7 @@ package org.cloudbus.cloudsim.cloudlets;
import org.cloudbus.cloudsim.vms.Vm;
import org.cloudbus.cloudsim.brokers.DatacenterBroker;
import org.cloudbus.cloudsim.datacenters.Datacenter;