因为做实验需要用到host的负载信息,希望输出中包括host的CPU,RAM,storage,BW的使用率,所以研究一下。

用的例子是package org.cloudbus.cloudsim.examples中的CloudSimExample1。

直接运行一下看一下输出:

之后我用的是比较麻烦的方法以加深一下理解,将输出与代码对应起来,找到每一步是在哪运行的。

首先Starting CloudSimExample1...就不说了,是在CloudSimExample1中的主函数第一句进行输出的。之后是第一步初始化CloudSim包,这个操作要在创建任何实体(DC,broker)之前做,在cloudsim自带的例子中也是标准的第一步,这里有这一句:CloudSim.init(num_user, calendar, trace_flag);这个方法创建了一个CIS(CloudInformationService),之后整个程序的运行都在依托这个CIS来运行。

之后是第二部创建数据中心;

第三步创建代理;

第四步创建vm列表,然后把这个vmlist上传到broker中去;

第五步差不多,创建cloudlet,然后上传给broker。到此为止都是准备工作,之后程序的运行要去看broker里的代码。

第六步:开始仿真

CloudSim.startSimulation();这句代码开始仿真,点进去startSimulation()看其代码:

public static double startSimulation() throws NullPointerException {Log.printConcatLine("Starting CloudSim version ", CLOUDSIM_VERSION_STRING);try {double clock = run();// reset all static variablescisId = -1;shutdownId = -1;cis = null;calendar = null;traceFlag = false;return clock;} catch (IllegalArgumentException e) {e.printStackTrace();throw new NullPointerException("CloudSim.startCloudSimulation() :"+ " Error - you haven't initialized CloudSim.");}}

可以看到这段代码输出的一句“Starting CloudSim version”,与输出中的信息相对应。这段代码中运行的这一方法:"double clock = run()",点进去看run()方法:

public static double run() {if (!running) {runStart();}while (true) {if (runClockTick() || abruptTerminate) {break;}// this block allows termination of simulation at a specific timeif (terminateAt > 0.0 && clock >= terminateAt) {terminateSimulation();clock = terminateAt;break;}if (pauseAt != -1&& ((future.size() > 0 && clock <= pauseAt && pauseAt <= future.iterator().next().eventTime()) || future.size() == 0 && pauseAt <= clock)) {pauseSimulation();clock = pauseAt;}while (paused) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}double clock = clock();finishSimulation();runStop();return clock;}

这个方法是开启仿真的主函数,但是需要在所有entity(DC,broker)启动之后才可以运行,所以该方法首先调用了runStart()方法:

public static void runStart() {running = true;// Start all the entitiesfor (SimEntity ent : entities) {ent.startEntity();}printMessage("Entities started.");}

该方法中,使用了一个for循环来调用每个entity(Datacenter,broker)的startEntity()方法,接下来就要去Datacenter和DatacenterBroker类中去看一下这两个entity的startEntitiy方法:

Datacenter:

public void startEntity() {Log.printConcatLine(getName(), " is starting...");// this resource should register to regional CIS.// However, if not specified, then register to system CIS (the// default CloudInformationService) entity.int gisID = CloudSim.getEntityId(regionalCisName);if (gisID == -1) {gisID = CloudSim.getCloudInfoServiceEntityId();}// send the registration to CISsendNow(gisID, CloudSimTags.REGISTER_RESOURCE, getId());// Below method is for a child class to overrideregisterOtherEntity();}

DatacneterBroker:

public void startEntity() {Log.printConcatLine(getName(), " is starting...");schedule(getId(), 0, CloudSimTags.RESOURCE_CHARACTERISTICS_REQUEST);}

这两个entity的启动都会输出一句”....is starting“,然后将自身的注册信息发送到CIS中。DatacenterBroker的方法中,调用了schedule的方法,将该event打上RESOURCE_CHARACTERISTICS_REQUEST的标签加入到了事件队列future中,future保存的是要运行的simevent队列。

在每个entity都启动完成后runStart()就会输出”Entities started.“

接着回到仿真运行的方法run()中去,在接下来的while循环中调用了方法runClockTick(),这是运行模拟一个时钟刻度的方法:

public static boolean runClockTick() {SimEntity ent;boolean queue_empty;int entities_size = entities.size();for (int i = 0; i < entities_size; i++) {ent = entities.get(i);if (ent.getState() == SimEntity.RUNNABLE) {ent.run();}}// If there are more future events then deal with themif (future.size() > 0) {List<SimEvent> toRemove = new ArrayList<SimEvent>();Iterator<SimEvent> fit = future.iterator();queue_empty = false;SimEvent first = fit.next();processEvent(first);future.remove(first);fit = future.iterator();// Check if next events are at same time...boolean trymore = fit.hasNext();while (trymore) {SimEvent next = fit.next();if (next.eventTime() == first.eventTime()) {processEvent(next);toRemove.add(next);trymore = fit.hasNext();} else {trymore = false;}}future.removeAll(toRemove);} else {queue_empty = true;running = false;printMessage("Simulation: No more future events");}return queue_empty;}

在该方法的第一个for循环中,每个entity调用方法run(),这个run()是类SimEntity中定义的run():

public void run() {SimEvent ev = evbuf != null ? evbuf : getNextEvent();while (ev != null) {processEvent(ev);if (state != RUNNABLE) {break;}ev = getNextEvent();}evbuf = null;}

这个方法中调用了方法”processEvent()",这在SimEntity类中是一个抽象方法,需要子类具体去实现,接下来看DatacenterBroker中实现的processEvent()方法:

@Overridepublic void processEvent(SimEvent ev) {switch (ev.getTag()) {// Resource characteristics requestcase CloudSimTags.RESOURCE_CHARACTERISTICS_REQUEST:processResourceCharacteristicsRequest(ev);break;// Resource characteristics answercase CloudSimTags.RESOURCE_CHARACTERISTICS:processResourceCharacteristics(ev);break;// VM Creation answercase CloudSimTags.VM_CREATE_ACK:processVmCreate(ev);break;// A finished cloudlet returnedcase CloudSimTags.CLOUDLET_RETURN:processCloudletReturn(ev);break;// if the simulation finishescase CloudSimTags.END_OF_SIMULATION:shutdownEntity();break;// other unknown tags are processed by this methoddefault:processOtherEvent(ev);break;}}

broker中的这个方法会根据时间标签来调用不同的方法,在该例子中,首先根据标签RESOURCE_CHARACTERISTICS_REQUEST调用了processResourceCharacteristicsRequest方法,先输出日志“0.0: Broker: Cloud Resource List received with 1 resource(s)”。然后设定数据中心ID,将下一个事件(CloudSimTags.RESOURCE_CHARACTERISTICS:)的注册信息发送到CIS,将该事件加入到future队列中去。之后在run()方法的循环中再次调用DatacenterBroker的processEvent方法,找到对应的标签,调用对应的方法“processResourceCharacteristics”,这方法处理对数据中心请求的返回,之后发送创建vm的信息向CIS,也就是标签为“VM_CREATE_ACK”的事件(event),之后以此类推,在DatacenterBroker的processEvent执行期间,像这样先执行一个事件,在执行该事件时将下一个事件添加到要执行的事件队列中去。

在方法“processVmCreate(ev)”中:

protected void processVmCreate(SimEvent ev) {int[] data = (int[]) ev.getData();int datacenterId = data[0];int vmId = data[1];int result = data[2];if (result == CloudSimTags.TRUE) {getVmsToDatacentersMap().put(vmId, datacenterId);getVmsCreatedList().add(VmList.getById(getVmList(), vmId));Log.printConcatLine(CloudSim.clock(), ": ", getName(), ": VM #", vmId," has been created in Datacenter #", datacenterId, ", Host #",VmList.getById(getVmsCreatedList(), vmId).getHost().getId());} else {Log.printConcatLine(CloudSim.clock(), ": ", getName(), ": Creation of VM #", vmId," failed in Datacenter #", datacenterId);}incrementVmsAcks();// all the requested VMs have been createdif (getVmsCreatedList().size() == getVmList().size() - getVmsDestroyed()) {submitCloudlets();} else {// all the acks received, but some VMs were not createdif (getVmsRequested() == getVmsAcks()) {// find id of the next datacenter that has not been triedfor (int nextDatacenterId : getDatacenterIdsList()) {if (!getDatacenterRequestedIdsList().contains(nextDatacenterId)) {createVmsInDatacenter(nextDatacenterId);return;}}// all datacenters already queriedif (getVmsCreatedList().size() > 0) { // if some vm were createdsubmitCloudlets();} else { // no vms created. abortLog.printLine(CloudSim.clock() + ": " + getName()+ ": none of the required VMs could be created. Aborting");finishExecution();}}}}

在所有VM都创建完毕之后,将cloudlet分配给vm:

protected void submitCloudlets() {int vmIndex = 0;List<Cloudlet> successfullySubmitted = new ArrayList<Cloudlet>();for (Cloudlet cloudlet : getCloudletList()) {Vm vm;// if user didn't bind this cloudlet and it has not been executed yetif (cloudlet.getVmId() == -1) {vm = getVmsCreatedList().get(vmIndex);} else { // submit to the specific vmvm = VmList.getById(getVmsCreatedList(), cloudlet.getVmId());if (vm == null) { // vm was not createdif(!Log.isDisabled()) {                    Log.printConcatLine(CloudSim.clock(), ": ", getName(), ": Postponing execution of cloudlet ",cloudlet.getCloudletId(), ": bount VM not available");}continue;}}if (!Log.isDisabled()) {Log.printConcatLine(CloudSim.clock(), ": ", getName(), ": Sending cloudlet ",cloudlet.getCloudletId(), " to VM #", vm.getId());}cloudlet.setVmId(vm.getId());sendNow(getVmsToDatacentersMap().get(vm.getId()), CloudSimTags.CLOUDLET_SUBMIT, cloudlet);cloudletsSubmitted++;vmIndex = (vmIndex + 1) % getVmsCreatedList().size();getCloudletSubmittedList().add(cloudlet);successfullySubmitted.add(cloudlet);}// remove submitted cloudlets from waiting listgetCloudletList().removeAll(successfullySubmitted);}

这个broker中的cloudlet分配只是简单的分配,分配完之后,该方法调用sendNow()将事件标签为“CLOUDLET_SUBMIT”加入事件列表中,这个事件由Datacenter来处理:

protected void processCloudletSubmit(SimEvent ev, boolean ack) {updateCloudletProcessing();try {// gets the Cloudlet objectCloudlet cl = (Cloudlet) ev.getData();// checks whether this Cloudlet has finished or notif (cl.isFinished()) {String name = CloudSim.getEntityName(cl.getUserId());Log.printConcatLine(getName(), ": Warning - Cloudlet #", cl.getCloudletId(), " owned by ", name," is already completed/finished.");Log.printLine("Therefore, it is not being executed again");Log.printLine();// NOTE: If a Cloudlet has finished, then it won't be processed.// So, if ack is required, this method sends back a result.// If ack is not required, this method don't send back a result.// Hence, this might cause CloudSim to be hanged since waiting// for this Cloudlet back.if (ack) {int[] data = new int[3];data[0] = getId();data[1] = cl.getCloudletId();data[2] = CloudSimTags.FALSE;// unique tag = operation tagint tag = CloudSimTags.CLOUDLET_SUBMIT_ACK;sendNow(cl.getUserId(), tag, data);}sendNow(cl.getUserId(), CloudSimTags.CLOUDLET_RETURN, cl);return;}// process this Cloudlet to this CloudResourcecl.setResourceParameter(getId(), getCharacteristics().getCostPerSecond(), getCharacteristics().getCostPerBw());int userId = cl.getUserId();int vmId = cl.getVmId();// time to transfer the filesdouble fileTransferTime = predictFileTransferTime(cl.getRequiredFiles());Host host = getVmAllocationPolicy().getHost(vmId, userId);Vm vm = host.getVm(vmId, userId);CloudletScheduler scheduler = vm.getCloudletScheduler();double estimatedFinishTime = scheduler.cloudletSubmit(cl, fileTransferTime);// if this cloudlet is in the exec queueif (estimatedFinishTime > 0.0 && !Double.isInfinite(estimatedFinishTime)) {estimatedFinishTime += fileTransferTime;send(getId(), estimatedFinishTime, CloudSimTags.VM_DATACENTER_EVENT);}if (ack) {int[] data = new int[3];data[0] = getId();data[1] = cl.getCloudletId();data[2] = CloudSimTags.TRUE;// unique tag = operation tagint tag = CloudSimTags.CLOUDLET_SUBMIT_ACK;sendNow(cl.getUserId(), tag, data);}} catch (ClassCastException c) {Log.printLine(getName() + ".processCloudletSubmit(): " + "ClassCastException error.");c.printStackTrace();} catch (Exception e) {Log.printLine(getName() + ".processCloudletSubmit(): " + "Exception error.");e.printStackTrace();}checkCloudletCompletion();}

在datacenter中对上传的任务处理完成后,broker中处理任务返回的信息:

protected void processCloudletReturn(SimEvent ev) {Cloudlet cloudlet = (Cloudlet) ev.getData();getCloudletReceivedList().add(cloudlet);Log.printConcatLine(CloudSim.clock(), ": ", getName(), ": Cloudlet ", cloudlet.getCloudletId()," received");cloudletsSubmitted--;if (getCloudletList().size() == 0 && cloudletsSubmitted == 0) { // all cloudlets executedLog.printConcatLine(CloudSim.clock(), ": ", getName(), ": All Cloudlets executed. Finishing...");clearDatacenters();finishExecution();} else { // some cloudlets haven't finished yetif (getCloudletList().size() > 0 && cloudletsSubmitted == 0) {// all the cloudlets sent finished. It means that some bount// cloudlet is waiting its VM be createdclearDatacenters();createVmsInDatacenter(0);}}}

最终清理Datacenters删除vm

之后在entity中调用shutdownEntity关掉DC和broker,打印结果。

CloudSim仿真流程研究(一)相关推荐

  1. CloudSim仿真流程

    CloudSim基础仿真流程总结 这是在阅读CloudSim Example1用例代码后,对CloudSim仿真流程的一点总结 类 类总结: DataCenter类 数据中心,提供虚拟化网络资源 (封 ...

  2. 潮流仿真分析matlab,基于MATLAB的电力系统潮流仿真与研究

    DOI:10. 13888/j. cnki. jsie(ns). 2019. 02. 008 收稿日期:2018 - 07 - 17 基金项目:国家自然科学基金青年项目(61803271)作者简介:刘 ...

  3. 计算机仿真相关文献有哪些,计算机仿真技术研究论文

    仿真的建模方法.采用的仿真计算机平台及文件开发软件是关系到仿真技术发展的关键.下面是学习啦小编为大家整理的计算机仿真技术研究论文,供大家参考. 计算机仿真技术研究论文范文一:牵引供电系统计算机仿真研究 ...

  4. matlab的多变量dmc源程序,基于MATLAB多变量DMC算法的仿真技术研究

    基于MATLAB多变量DMC算法的仿真技术研究 基于MATLAB多变量DMC算法的仿真技术研究 作者:李凤霞 于佐军 来源:<科技创新导报>2011年第17期 摘 要:利用MATLAB开发 ...

  5. Cadence数模混合仿真流程

    Cadence数模混合仿真流程 1.进入Libraty Manager界面 2. 新建cell(digital)单元 3. 选择 cell type及编辑器 4. 为cell命名并编写verilog代 ...

  6. modelsim的工程仿真流程--2

    文章目录 引言 创建工程及工程库 加载设计文件 运行仿真 保存波形文件wlf 基本仿真流程与工程仿真流程方法对比 附录 引言 首先建立一个工程,然后向工程中添加设计文件,接下来编译设计文件,之后运行仿 ...

  7. 计算机网络通信的仿真,计算机网络虚拟仿真技术研究与应用.doc

    计算机网络虚拟仿真技术研究与应用 计算机网络虚拟仿真技术研究与应用 摘 要: 虚拟仿真技术也日趋成熟,已经应用到了科学.生活等各个领域,许多高校也开始将虚拟仿真技术应用到实际教学中.传统的实验教学受到 ...

  8. Modelsim仿真流程

    Modelsim仿真流程 1. Modelsim简介 略. 2. modelsim仿真流程:modelsim基本的仿真流程包括建立库.建立工程并编译.仿真.调试.但在libero环境中运行models ...

  9. 在线激活流程研究, 芯片杂烩, 软件滤波算法

    在线激活流程研究 在世界范围内,软件的盗版问题都是个令程序员苦恼的问题.相应的,很多反盗版的措施也就应运而生.其中以输入序列号.激活码的产品激活策略应用最为广泛.本文就从流程的角度粗略的描述一下这个过 ...

  10. matlab sar 斑马图,星载合成孔径雷达(SAR)斑马图仿真与研究

    收稿日期:2002 - 04 - 22 第 20 卷 第 5 期 计 算 机 仿 真 2003 年 5 月 文章编号:1006 - 9348(2003)05 - 0123 - 04 星载合成孔径雷达( ...

最新文章

  1. 程序员语言也有鄙视链!某美团程序员爆料:筛选简历时,用go语言的基本不看!网友:当韭菜还当出优越感了!...
  2. 如何让人工智能更智能?你需要一个开源平台
  3. 盘点上海AI行业的10岁、20岁和30岁们
  4. 动态规划(最长递增子序列)---最长摆动子序列
  5. 如何使用Windows搜索在任何文件中搜索文本
  6. 【转】消息队列应用场景
  7. Linux之find常用命令汇总
  8. centos安装mysql wsl_windows 10 WSL 安装 Centos
  9. python selenium文件下载
  10. Android ImageView实现反色显示的方法
  11. labelme转VOC2007格式
  12. JavaWeb购物系统(课程设计)
  13. 图片在线转换成word免费版
  14. 通信(一) 串口通信
  15. 米兔机器人终于拼完了_米兔机器人上手组装如果你不会拼装或拆卸建议收藏
  16. java 定义别名_为java类起别名
  17. 基于Pytorch实现的声纹识别模型
  18. 改善到底多大 FXAA画质游戏实测
  19. vue-router 路由 pushstate replacestate popstate 详解
  20. 知名插画师走尺,带你走进“薪”世界

热门文章

  1. 74HC595驱动数码管显示模块使用说明
  2. css字间距 与 Photoshop里字间距关系
  3. 医院时钟系统(网络授时设备)设计方案
  4. java对打字速度,java课程设计-- 打字速度测试程序
  5. HTTP状态码404、413、500
  6. 应付职称评定的论文-《七星彩神经网络预测系统》原型开发构想
  7. 【95】太空射击游戏——玩家代码
  8. 华硕笔记本怎么安装计算机,华硕笔记本电脑驱动怎么安装(一次装全,Win10)...
  9. Gimp去除图片背景色方法
  10. ffmpeg 转换flv压缩大小_ffmpeg 视频压缩 转换