由于毕设需要使用了edgecloudsim环境,记录了相关代码、架构和环境设置,作为辅助参考。

环境疑点
  • 环境没有网络拓扑,移动设备通过无线局域网和适配器连接,用户设备通过nomadic mobility model(游牧模型)动态移动。环境内包含多个适配器,移动设备给最近的适配器发送任务。
  • 网络信息包含:wlan、wan、平均时延,根据wan用户数得到带宽,除以任务数据大小得到时延
  • 完成任务所需时间:根据任务在节点完成时间和占用cpu生成节点剩余算力,计算完成任务所需的时间。在DeepMobileDeviceManager101行,该处处理任务返回,如果在进行附近边缘计算,则下载时延使用wlan有关属性计算;同理如果在相邻边缘计算,则下载时延为man,在云则为wan;该段代码在jar包内。
  • 用户请求由适配器决定卸载到云和边,那么到适配器的时延怎么表示?:强化学习model的决策代码不在适配器完成,适配器仅作为处理选择的主机里容量最多的VM占用:dqn做出决策以后,下一跳是云或边缘,任务被边缘下载后通过适配器选择VM,如果选定VM不在本地,则通过man转发给相邻边缘,相邻边缘接收并提交给VM。只要选定边缘设备上传时延都是wlan。
  • 虚拟机代表什么?有14个数据中心,每个中心有一个host,里面有八个虚拟机(edge_device.xml);云数据中心有一个host,其中有四个虚拟机(default_config.properties配置)。
  • 关注状态中的算力和网络信息:处理任务所需算力,广域网带宽、城域网时延、任务生成设备和时间敏感度、各节点负载、任务数
  • 虚拟机带宽是均匀分布的,如果占用超额会导致rejectedDueToVMCapacity。
  • 任务失败原因:由于带宽失败、由于用户移动失败、由于分配的算力节点算力不够而失败。
文件记录

networkingModel:定义了wlan时延、wan时延带宽(20703)

DeepMobileDeviceManager:currentState

utils/SimLogger/Simlogger

simStopped():定义了数据记录

代码解读

processEvent: cloudInformationService、DatacenterBroke、datacenter

processCloudletSubmit处理云任务提交位置:edgeCloudSim-DeepEdge\lib\cloudsim-4.0.jar\org\cloudbus\cloudsim\Datacenter\processCloudletSubmit

    protected void processCloudletSubmit(SimEvent ev, boolean ack) {//只能被当前类、子类以及同包类访问
        this.updateCloudletProcessing();//更新云任务的处理状态

        try {//尝试检查任务完成状态并发送ack
            Cloudlet cl = (Cloudlet)ev.getData();
            if (cl.isFinished()) {
                String name = CloudSim.getEntityName(cl.getUserId());
                Log.printConcatLine(new Object[]{this.getName(), ": Warning - Cloudlet #", cl.getCloudletId(), " owned by ", name, " is already completed/finished."});
                Log.printLine("Therefore, it is not being executed again");
                Log.printLine();
                if (ack) {
                    int[] data = new int[]{this.getId(), cl.getCloudletId(), 0};
                    int tag = 22;
                    this.sendNow(cl.getUserId(), tag, data);
                }

                this.sendNow(cl.getUserId(), 20, cl);
                return;
            }

            cl.setResourceParameter(this.getId(), this.getCharacteristics().getCostPerSecond(), this.getCharacteristics().getCostPerBw());//获得资源参数
            int userId = cl.getUserId();//任务用户ID
            int vmId = cl.getVmId();//执行虚拟机ID
            double fileTransferTime = this.predictFileTransferTime(cl.getRequiredFiles());//预测传输时间,可能计算文件大小和带宽
            Host host = this.getVmAllocationPolicy().getHost(vmId, userId);//获得主机
            Vm vm = host.getVm(vmId, userId);
            CloudletScheduler scheduler = vm.getCloudletScheduler();//云任务调度器
            double estimatedFinishTime = scheduler.cloudletSubmit(cl, fileTransferTime);//通过预计时间,调度返回估计的完成时间
            if (estimatedFinishTime > 0.0D && !Double.isInfinite(estimatedFinishTime)) {
                estimatedFinishTime += fileTransferTime;//完成时间+=传输时间
                this.send(this.getId(), estimatedFinishTime, 41);//发送完成时间信息
            }

            if (ack) {
                int[] data = new int[]{this.getId(), cl.getCloudletId(), 1};
                int tag = 22;
                this.sendNow(cl.getUserId(), tag, data);//通过id通知用户
            }
        } catch (ClassCastException var15) {
            Log.printLine(this.getName() + ".processCloudletSubmit(): " + "ClassCastException error.");
            var15.printStackTrace();
        } catch (Exception var16) {
            Log.printLine(this.getName() + ".processCloudletSubmit(): " + "Exception error.");
            var16.printStackTrace();
        }

        this.checkCloudletCompletion();//检查任务完成状态
    }
time += (double)tempFile.getSize() / tempStorage.getMaxTransferRate();//预计传输时间计算,遍历每个文件
predictFileTransferTime
  1. 初始化
    • time变量被初始化为0.0D,用来累计总的文件传输时间。
  2. 遍历所需文件
    • 使用Iterator遍历requiredFiles列表,这个列表包含了所有需要传输的文件名。
  3. 查找文件并计算传输时间
    • 对于每个文件名,代码遍历getStorageList返回的存储列表。这个列表可能包含了多个存储单元或存储设备。
    • 在每个存储单元中,代码尝试使用文件名获取File对象。
    • 如果找到了对应的文件(即tempFile不为null),则计算文件的传输时间。传输时间是通过将文件大小(tempFile.getSize())除以存储单元的最大传输速率(tempStorage.getMaxTransferRate())来得到的。
    • 一旦找到了文件并计算了传输时间,代码会跳出内层循环(即不再检查其他存储单元),并将传输时间累加到time变量中。
  4. 返回总传输时间
    • 在完成对所有所需文件的遍历后,方法返回累计的总传输时间time
cloudletSubmit

在这里插入图片描述

    public double cloudletSubmit(Cloudlet cloudlet, double fileTransferTime) {
        ResCloudlet rcl = new ResCloudlet(cloudlet);
        rcl.setCloudletStatus(3);

        for(int i = 0; i < cloudlet.getNumberOfPes(); ++i) {
            rcl.setMachineAndPeId(0, i);//模拟云任务分配具体的计算资源
        }

        this.getCloudletExecList().add(rcl);//将执行结果添加到执行列表
        double extraSize = this.getCapacity(this.getCurrentMipsShare()) * fileTransferTime;//通过MIPS份额和传输时间计算额外云任务长度
        long length = (long)((double)cloudlet.getCloudletLength() + extraSize);
        cloudlet.setCloudletLength(length);
        return (double)cloudlet.getCloudletLength() / this.getCapacity(this.getCurrentMipsShare());//通过更新任务指令长度/MIPS份额(每秒百万条指令),计算预计时间
    }
  1. 文件传输时间(fileTransferTime:这个参数通常代表将任务(Cloudlet)所需的数据从存储位置传输到执行该任务的主机或虚拟机所需的时间。这可以是网络传输时间、磁盘I/O时间,或其他任何形式的数据迁移时间。
  2. 主机的处理能力(getCapacity(this.getCurrentMipsShare()):这个方法通常返回当前主机或虚拟机在给定的MIPS(百万条指令每秒)共享设置下的计算能力。MIPS是一个衡量处理器速度的指标,它反映了处理器每秒钟可以执行的指令数量。在这里,它被用来衡量主机在文件传输时间内可以处理多少额外的工作。
  3. 计算extraSizeextraSize 是通过将主机的处理能力乘以文件传输时间来计算的。这可以理解为,在数据被传输到主机并开始执行Cloudlet的这段时间内,主机本来可以处理的其他工作量。换句话说,extraSize 代表了由于文件传输造成的计算资源的潜在浪费。
  4. 更新Cloudlet的长度:通过将 extraSize 加到 cloudlet 的原始长度上,模拟环境考虑到了文件传输时间对任务执行总时间的影响。这确保了当评估任务的完成时间或性能时,不仅考虑了实际的计算时间,还考虑了数据传输所需的时间。
  5. 返回执行时间:最后,通过将更新后的 cloudletLength 除以主机的处理能力,计算出任务在主机上的预期执行时间。这个返回值对于调度决策、性能分析和资源规划等任务非常重要。
protected double getCapacity(List<Double> mipsShare) {
    double capacity = 0.0D;
    int cpus = 0;
    Iterator var5 = mipsShare.iterator();

    while(var5.hasNext()) {//遍历
        Double mips = (Double)var5.next();
        capacity += mips;//累加
        if (mips > 0.0D) {
            ++cpus;
        }
    }

    this.currentCPUs = cpus;
    int pesInUse = 0;

    ResCloudlet rcl;
    for(Iterator var9 = this.getCloudletExecList().iterator(); var9.hasNext(); pesInUse += rcl.getNumberOfPes()) {//累加每个云任务所使用的处理单元
        rcl = (ResCloudlet)var9.next();
    }

    if (pesInUse > this.currentCPUs) {
        capacity /= (double)pesInUse;
    } else {
        capacity /= (double)this.currentCPUs;
    }

    return capacity;
}
  1. MIPS 共享列表(mipsShare

    mipsShare 列表中的每个元素代表了一个处理单元(PE)的 MIPS 值。列表中的 MIPS 值累加起来构成了主机的总 MIPS 容量。如果列表中的 MIPS 值发生变化(例如,由于动态资源分配或主机升级),则主机的总 MIPS 容量也会相应改变。

  2. 处理单元数量(cpus

    cpus 变量记录了 mipsShare 列表中 MIPS 值大于 0 的元素数量,即实际可用的处理单元数量。如果某些处理单元被关闭或不可用,或者新的处理单元被添加,那么 cpus 的值会改变,进而影响 MIPS 容量的计算。

  3. 正在执行的任务(Cloudlet)

    代码中的第二个循环遍历了当前正在执行的任务列表(getCloudletExecList),并计算了这些任务所使用的 PE 数量(pesInUse)。这个值用于确定如何分配主机的 MIPS 容量。如果 pesInUse 大于 currentCPUs,则 MIPS 容量会被更平均地分配到每个正在使用的 PE 上;否则,它会被平均分配到每个可用的 PE 上。因此,正在执行的任务数量以及它们所使用的 PE 数量会影响 MIPS 的分配。

  4. 任务调度和资源管理策略

    任务调度策略决定了哪些任务在何时被分配到主机上执行,以及它们使用多少 PE。资源管理策略可能动态地调整 MIPS 共享列表,以响应系统负载变化或优化性能。这些策略的变化会直接影响 getCapacity 方法计算出的 MIPS 容量。

  5. 系统动态性和负载变化

    在实际运行的云计算环境中,系统的负载是动态变化的。随着新任务的到达和现有任务的完成,主机的 MIPS 容量和分配可能会不断变化。此外,其他系统因素(如网络延迟、存储性能等)也可能间接影响 MIPS 的有效利用。

综上所述,MIPS 的计算受到多种因素的影响,包括分配给主机的 MIPS 共享、处理单元的数量和可用性、正在执行的任务以及它们所使用的资源、任务调度和资源管理策略,以及系统的动态性和负载变化。这些因素共同决定了主机的计算能力,并影响着任务的执行效率。

MIPS份额:衡量处理器速度,用于表示机器计算能力

由多个用户运行的不同应用程序的泊松式,该操作并不能完全确定下一个状态(4.3节):如果需要其他任务生成或移动性模型,则应修改移动设备管理器模块。应该注意的是,数据大小和任务长度的分布应根据任务的生成分布来确定。默认情况下,这些变量是指数分布的随机数,因为任务是根据泊松分布到达的。

任务失败代码——if(delay、rejectedDue、failedDue:176,287行

任务有返回时训练一次。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐