CloudSim Plus 能耗仿真(二)

  • Post author:
  • Post category:其他




CloudSim Plus 能耗仿真(二)



能耗仿真

  1. 主机需要定义

    PowerModel

    final PowerModelHost powerModel = new PowerModelHostSimple(145,15);
    host.setPowerModel(powerModel)
    
  2. 启用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();
    
  3. 在数据中心实体内部统计数据

    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 版权协议,转载请附上原文出处链接和本声明。