CloudSim Plus 能耗仿真(二)
能耗仿真
-
主机需要定义
PowerModel
final PowerModelHost powerModel = new PowerModelHostSimple(145,15); host.setPowerModel(powerModel)
-
启用CPU历史数据(
CPU Utilization History
)
Realize that the Host CPU Utilization History is only stored if VMs utilization history is enabled by calling {@code vm.enableUtilizationStats()}
虚拟机利用率数据统计
vm.enableUtilizationStats()
主机利用率数据统计
host.enableUtilizationStats();
-
在数据中心实体内部统计数据
package test; import org.cloudbus.cloudsim.core.CloudSim; import org.cloudbus.cloudsim.core.events.SimEvent; import org.cloudbus.cloudsim.datacenters.DatacenterSimple; import org.cloudbus.cloudsim.hosts.Host; import java.util.ArrayList; import java.util.List; /** * @Author: mhh * @Date: 2022/5/30 * @Description: 数据中心实体 */ public class DataCenter extends DatacenterSimple { // 设置的仿真时间,默认60秒 private int SIMULATION_TIME = 60; protected CloudSim simulationManager; // 记录CPU利用率变化 protected List<Double> utilizationStats; // 记录能耗消耗变化 protected List<Double> energyConsumptionStats; private static final int BASE_TAG = 1000; private static final int UPDATE_STATUS = BASE_TAG + 1; public DataCenter(CloudSim simulation, List<? extends Host> hostList) { super(simulation, hostList); this.simulationManager = simulation; this.utilizationStats = new ArrayList<>(); this.energyConsumptionStats = new ArrayList<>(); } @Override protected void startInternal() { super.startInternal(); schedule(this, 1, UPDATE_STATUS); } @Override public void processEvent(SimEvent evt) { switch (evt.getTag()) { case UPDATE_STATUS: // 根据更新间隔更新状态 if (getSimulation().clock() < SIMULATION_TIME) { utilizationStats.add(getCurrentUtilization()); energyConsumptionStats.add(getCurrentEnergyCompustion()); schedule(this, getSchedulingInterval(), UPDATE_STATUS); } break; default: super.processEvent(evt); break; } } private double getCurrentEnergyCompustion() { double energyCompustion = 0; for (Host host : getHostList()) { double hostCpuPercentUtilization = host.getCpuPercentUtilization(); double power = host.getPowerModel().getPower(hostCpuPercentUtilization) * getSchedulingInterval(); energyCompustion += power; } return energyCompustion; } private double getCurrentUtilization() { double totalUtilization = getHostList().stream().mapToDouble(Host::getCpuPercentUtilization).sum(); return totalUtilization / getHostList().size() * 100.0; } public void setSimulationTime(int simulationTime) { SIMULATION_TIME = simulationTime; } public List<Double> getUtilizationStats() { return utilizationStats; } public List<Double> getEnergyConsumptionStats() { return energyConsumptionStats; } }
实例代码
public class PowerModelTest {
private static final int SCHEDULING_INTERVAL = 1;
private static final int SIMULATION_TIME = 600;
private static final int WAIT_TASK_TIME = 5;
private static final int HOSTS = 2;
private static final int HOST_PES = 10;
private static final int VMS = 20;
private static final int VM_PES = 1;
private final CloudSim simulation;
private final List<Host> hostList;
public static void main(String[] args) {
new PowerModelTest();
}
private PowerModelTest() {
Log.setLevel(Level.INFO);
simulation = new CloudSim(0.001);
hostList = new ArrayList<>(HOSTS);
DataCenter dataCenter = (DataCenter) createDatacenter();
DatacenterBroker broker0 = new DatacenterBrokerSimple(simulation);
List<Vm> vmList = createVms();
List<Cloudlet> cloudletList = createCloudletList(SIMULATION_TIME);
broker0.submitVmList(vmList);
broker0.submitCloudletList(cloudletList);
simulation.terminateAt(SIMULATION_TIME + WAIT_TASK_TIME);
simulation.start();
final List<Cloudlet> finishedCloudlets = broker0.getCloudletFinishedList();
final Comparator<Cloudlet> hostComparator = comparingLong(cl -> cl.getVm().getHost().getId());
finishedCloudlets.sort(hostComparator.thenComparing(cl -> cl.getVm().getId()));
new CloudletsTableBuilder(finishedCloudlets).build();
// 绘制图像(本人写的工具类)
XYChartGenerate chartGenarete = new XYChartGenerate();
chartGenarete.setSize(1600,400)
.setAxisTitle("Time(s)","energy(W·s)")
.initChart()
.addSeriesData("energy",null, dataCenter.getEnergyConsumptionStats().stream().mapToDouble(t -> t).toArray())
.saveChart("energy");
chartGenarete.setSize(1600,400)
.setAxisTitle("Time(s)","Utilization(%)")
.initChart()
.addSeriesData("utilization",null, dataCenter.getUtilizationStats().stream().mapToDouble(t -> t).toArray())
.saveChart("utilization");
}
private Datacenter createDatacenter() {
for(int i = 0; i < HOSTS; i++) {
final Host host = createPowerHost(i);
hostList.add(host);
}
DataCenter dataCenter = new DataCenter(simulation, hostList);
// 设置更新的时间间隔
dataCenter.setSchedulingInterval(SCHEDULING_INTERVAL);
// 设置仿真时间
dataCenter.setSimulationTime(SIMULATION_TIME);
return dataCenter;
}
private Host createPowerHost(final int id) {
final List<Pe> peList = new ArrayList<>(HOST_PES);
for (int i = 0; i < HOST_PES; i++) {
peList.add(new PeSimple(3500));
}
final long ram = 20480;
final long bw = 100000;
final long storage = 1000000;
final VmSchedulerTimeShared vmScheduler = new VmSchedulerTimeShared();
final Host host = new HostSimple(ram, bw, storage, peList);
final PowerModelHost powerModel = new PowerModelHostSimple(145,15);
host.setId(id);
host.setVmScheduler(vmScheduler);
host.setPowerModel(powerModel);
host.enableUtilizationStats();
return host;
}
private List<Vm> createVms() {
final var list = new ArrayList<Vm>(VMS);
for (int i = 0; i < VMS; i++) {
final var vm = new VmSimple(i, 3500, VM_PES);
vm.setRam(1024)
.setBw(1000)
.setSize(10000)
.enableUtilizationStats();
list.add(vm);
}
return list;
}
/**
* 根据泊松分布来创建任务
* 产生时间:泊松分布
* 任务长度:指数分布
* @param simulationTime 仿真时间
* @return 任务列表
*/
public static List<Cloudlet> createCloudletList(double simulationTime) {
final List<Cloudlet> list = new ArrayList<>();
for (int currentTime = 5; currentTime < simulationTime; currentTime++) {
List<Cloudlet> cloudlets = createCloudlets(currentTime);
list.addAll(cloudlets);
}
return list;
}
/**
* 根据泊松分布来创建任务
* 产生时间:泊松分布
* 任务长度:指数分布
* @param currentTime 当前时间
* @return 任务列表
*/
private static List<Cloudlet> createCloudlets(double currentTime){
final int CLOUDLET_PES = 1; // 任务要求的 CPU 核
final double TASK_POISSON_LAMBDA = 3; // 任务到达时服从泊松分布 (平均3个/每秒)
final double TASK_EXPONENTIAL_MEAN = 10000; // 任务长度服从指数分布(20000)
List<Cloudlet> list = new ArrayList<>();
PoissonDistribution distribution = new PoissonDistribution(TASK_POISSON_LAMBDA);
ExponentialDistr taskDistr = new ExponentialDistr(TASK_EXPONENTIAL_MEAN);
// 每秒钟产生的任务数服从泊松分布
int taskNumber = distribution.sample();
for (int i = 0; i < taskNumber; i++) {
final UtilizationModelFull utilizationModel = new UtilizationModelFull();
long taskLength = (long) taskDistr.sample() + 500;
Cloudlet cloudlet = new CloudletSimple(taskLength, CLOUDLET_PES);
cloudlet.setUtilizationModel(utilizationModel)
.setUtilizationModelRam(new UtilizationModelDynamic())
.setUtilizationModelBw(new UtilizationModelDynamic())
.setSubmissionDelay(currentTime); // 设置任务到达时间
list.add(cloudlet);
}
return list;
}
}
仿真结果
-
CPU利用率变化
-
能量消耗变化
-
结果分析
由于主机功耗与CPU利用率成线性关系,所以能量消耗曲线与CPU利用率曲线大体一致。
版权声明:本文为maohuihua123原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。