GpuCloudSim初探:示例一
由于是第一个示例,所以我把一些参数的解释在后面一起加上了
package org.cloudbus.cloudsim.examples.gpu;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.cloudbus.cloudsim.Cloudlet;
import org.cloudbus.cloudsim.DatacenterCharacteristics;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.Pe;
import org.cloudbus.cloudsim.Storage;
import org.cloudbus.cloudsim.UtilizationModel;
import org.cloudbus.cloudsim.UtilizationModelFull;
import org.cloudbus.cloudsim.VmScheduler;
import org.cloudbus.cloudsim.VmSchedulerTimeShared;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.gpu.BusTags;
import org.cloudbus.cloudsim.gpu.GpuCloudlet;
import org.cloudbus.cloudsim.gpu.GpuCloudletSchedulerTimeShared;
import org.cloudbus.cloudsim.gpu.GpuDatacenter;
import org.cloudbus.cloudsim.gpu.GpuDatacenterBroker;
import org.cloudbus.cloudsim.gpu.GpuHost;
import org.cloudbus.cloudsim.gpu.GpuHostTags;
import org.cloudbus.cloudsim.gpu.GpuTask;
import org.cloudbus.cloudsim.gpu.GpuTaskSchedulerLeftover;
import org.cloudbus.cloudsim.gpu.GpuVm;
import org.cloudbus.cloudsim.gpu.GpuVmAllocationPolicySimple;
import org.cloudbus.cloudsim.gpu.GpuVmTags;
import org.cloudbus.cloudsim.gpu.Pgpu;
import org.cloudbus.cloudsim.gpu.Vgpu;
import org.cloudbus.cloudsim.gpu.VgpuScheduler;
import org.cloudbus.cloudsim.gpu.hardware_assisted.GridVgpuSchedulerFairShare;
import org.cloudbus.cloudsim.gpu.VideoCard;
import org.cloudbus.cloudsim.gpu.allocation.VideoCardAllocationPolicy;
import org.cloudbus.cloudsim.gpu.allocation.VideoCardAllocationPolicyBreadthFirst;
import org.cloudbus.cloudsim.gpu.hardware_assisted.GridVgpuTags;
import org.cloudbus.cloudsim.gpu.hardware_assisted.GridVideoCardTags;
import org.cloudbus.cloudsim.gpu.provisioners.BwProvisionerRelaxed;
import org.cloudbus.cloudsim.gpu.provisioners.GpuBwProvisionerShared;
import org.cloudbus.cloudsim.gpu.provisioners.GpuGddramProvisionerSimple;
import org.cloudbus.cloudsim.gpu.provisioners.VideoCardBwProvisioner;
import org.cloudbus.cloudsim.gpu.provisioners.VideoCardBwProvisionerShared;
import org.cloudbus.cloudsim.gpu.selection.PgpuSelectionPolicy;
import org.cloudbus.cloudsim.gpu.selection.PgpuSelectionPolicyBreadthFirst;
import org.cloudbus.cloudsim.lists.VmList;
import org.cloudbus.cloudsim.provisioners.PeProvisionerSimple;
import org.cloudbus.cloudsim.provisioners.RamProvisionerSimple;
import de.vandermeer.asciitable.AsciiTable;
/**
* This example demonstrates the use of gpu package in simulations. <br>
* GPU virtualization mode: hardware-assisted <br>
* Performance Model: off <br>
* Interference Model: off <br>
* Power Model: off
* 这个例子演示了gpu包在模拟中的使用。< br >
*
* * GPU虚拟化模式:硬件辅助
*
* *性能模型:关闭
*
* *干扰模型:off
*
* *电源型号:关闭
*
* @author Ahmad Siavashi
*
*/
public class CloudSimGpuExample1 {
/** 任务列表. */
private static List<GpuCloudlet> cloudletList;
/** 虚拟机列表. */
private static List<GpuVm> vmlist;
/** 虚拟机数量. */
private static int numVms = 1;
/** 任务数量 */
private static int numGpuCloudlets = 1;
/**
* The resolution in which progress in evaluated. 评估进展的决议 后面有进一步的解释
*/
private static double schedulingInterval = 20;
/**
* Creates main() to run this example.
*
* @param args
* the args
*/
@SuppressWarnings("unused")
public static void main(String[] args) {
Log.printLine("Starting CloudSimGpuExample1...");
try {
// number of cloud users 云用户的数量 与 时间戳
int num_user = 1;
Calendar calendar = Calendar.getInstance();
// trace events 跟踪事件
boolean trace_flag = true;
// CloudSim initialization CloudSim初始化
CloudSim.init(num_user, calendar, trace_flag);
// Create one Datacenter 创建一个数据中心
GpuDatacenter datacenter = createDatacenter("Datacenter");
// Create one Broker 创建一个数据中心代理
GpuDatacenterBroker broker = createBroker("Broker");
int brokerId = broker.getId();
// Create a list to hold created VMs 创建一个列表来存储虚拟机
vmlist = new ArrayList<GpuVm>();
// Create a list to hold issued Cloudlets 创建一个列表来存储任务 疑似重复了,被全局变量所覆盖
cloudletList = new ArrayList<GpuCloudlet>();
// Create VMs 创建虚拟机
for (int i = 0; i < numVms; i++) {
int vmId = i; // 虚拟机ID
int vgpuId = i; // gpu id
// Create a VM 创建一个虚拟机
GpuVm vm = createGpuVm(vmId, vgpuId, brokerId);
// add the VM to the vmList 增加这台虚拟机到虚拟机列表
vmlist.add(vm);
}
// Create gpuCloudlets 创建虚拟机列表
for (int i = 0; i < numGpuCloudlets; i++) {
int gpuCloudletId = i;
int gpuTaskId = i;
// Create Cloudlet 创建一个GPU任务
GpuCloudlet gpuCloudlet = createGpuCloudlet(gpuCloudletId, gpuTaskId, brokerId);
// add the cloudlet to the list 添加任务到列表中
cloudletList.add(gpuCloudlet);
}
// GpuCloudlet-VM assignment GpuCloudlet-VM赋值 进行映射 这里也可以作为调度
for (int i = 0; i < numGpuCloudlets; i++) { //顺序调度
GpuCloudlet gpuCloudlet = cloudletList.get(i);
gpuCloudlet.setVmId(i % numVms);
}
// submit vm list to the broker 提交虚拟机列表给代理
broker.submitVmList(vmlist);
// submit cloudlet list to the broker 提交任务列表给代理
broker.submitCloudletList(cloudletList);
// Disable Logs 关闭日志
Log.disable();
// Starts the simulation 开始仿真
CloudSim.startSimulation();
CloudSim.stopSimulation(); //停止仿真
Log.enable();
// Print results when simulation is over 输出结果,当仿真结束
List<Cloudlet> newList = broker.getCloudletReceivedList();
printCloudletList(newList);
Log.printLine("CloudSimGpuExample1 finished!");
} catch (Exception e) {
e.printStackTrace();
Log.printLine("Unwanted errors happen");
}
}
/**
* Create a GpuCloudlet 创建一个Gpu惹怒我 cloudlet
*
* @param gpuCloudletId
* gpuCloudlet id
* @param gpuTaskId
* gpuCloudlet's gpuTask id
* @param brokerId
* the broker to which the gpuCloudlet belongs gpuCloudlet所属的代理
* @return the gpuCloudlet
*/
private static GpuCloudlet createGpuCloudlet(int gpuCloudletId, int gpuTaskId, int brokerId) {
// Cloudlet properties 云任务属性 表示应用程序,下面有更进一步的解释
long length = (long) (400 * GpuHostTags.DUAL_INTEL_XEON_E5_2620_V3_PE_MIPS);
long fileSize = 300;
long outputSize = 300;
int pesNumber = 1;
# 利用模型 都为1
UtilizationModel cpuUtilizationModel = new UtilizationModelFull();
UtilizationModel ramUtilizationModel = new UtilizationModelFull();
UtilizationModel bwUtilizationModel = new UtilizationModelFull();
// GpuTask properties Gpu任务属性
long taskLength = (long) (GridVideoCardTags.NVIDIA_K1_CARD_PE_MIPS * 150);
long taskInputSize = 128;
long taskOutputSize = 128;
long requestedGddramSize = 4 * 1024;
int numberOfBlocks = 2;
// 利用率都为1
UtilizationModel gpuUtilizationModel = new UtilizationModelFull();
UtilizationModel gddramUtilizationModel = new UtilizationModelFull();
UtilizationModel gddramBwUtilizationModel = new UtilizationModelFull();
// gputask
GpuTask gpuTask = new GpuTask(gpuTaskId, taskLength, numberOfBlocks, taskInputSize, taskOutputSize,
requestedGddramSize, gpuUtilizationModel, gddramUtilizationModel, gddramBwUtilizationModel);
// gpucloudlet
GpuCloudlet gpuCloudlet = new GpuCloudlet(gpuCloudletId, length, pesNumber, fileSize, outputSize,
cpuUtilizationModel, ramUtilizationModel, bwUtilizationModel, gpuTask, false);
gpuCloudlet.setUserId(brokerId);
return gpuCloudlet;
}
/**
* Create a GpuVM
*
* @param vmId
* vm id
* @param vgpuId
* vm's vgpu id
* @param brokerId
* the broker to which this vm belongs
* @return the GpuVm
*/
private static GpuVm createGpuVm(int vmId, int vgpuId, int brokerId) {
// VM description
double mips = GpuHostTags.DUAL_INTEL_XEON_E5_2620_V3_PE_MIPS;
// image size (GB) 镜像大小
int size = 10;
// vm memory (GB) 虚拟机内存
int ram = 2;
long bw = 100; //带宽
// number of cpus
int pesNumber = 4; //cpu数量
// VMM name
String vmm = "vSphere"; //虚拟机名称
// Create a VM
GpuVm vm = new GpuVm(vmId, brokerId, mips, pesNumber, ram, bw, size, vmm, GpuVmTags.GPU_VM_CUSTOM,
new GpuCloudletSchedulerTimeShared());
// Create GpuTask Scheduler
GpuTaskSchedulerLeftover gpuTaskScheduler = new GpuTaskSchedulerLeftover();
// Create a Vgpu
Vgpu vgpu = GridVgpuTags.getK180Q(vgpuId, gpuTaskScheduler);
vm.setVgpu(vgpu);
return vm;
}
/**
* Create a datacenter.
*
* @param name
* the name of the datacenter
*
* @return the datacenter
*/
private static GpuDatacenter createDatacenter(String name) {
// We need to create a list to store our machines 创建一个列表来存储我们的机器
List<GpuHost> hostList = new ArrayList<GpuHost>();
// Number of host's video cards 主机显卡个数
int numVideoCards = GpuHostTags.DUAL_INTEL_XEON_E5_2620_V3_NUM_VIDEO_CARDS;
// To hold video cards 用来存放显卡
List<VideoCard> videoCards = new ArrayList<VideoCard>(numVideoCards);
for (int videoCardId = 0; videoCardId < numVideoCards; videoCardId++) {
List<Pgpu> pgpus = new ArrayList<Pgpu>();
// Adding an NVIDIA K1 Card
double mips = GridVideoCardTags.NVIDIA_K1_CARD_PE_MIPS;
int gddram = GridVideoCardTags.NVIDIA_K1_CARD_GPU_MEM;
long bw = GridVideoCardTags.NVIDIA_K1_CARD_BW_PER_BUS;
for (int pgpuId = 0; pgpuId < GridVideoCardTags.NVIDIA_K1_CARD_GPUS; pgpuId++) {
List<Pe> pes = new ArrayList<Pe>();
for (int peId = 0; peId < GridVideoCardTags.NVIDIA_K1_CARD_GPU_PES; peId++) {
pes.add(new Pe(peId, new PeProvisionerSimple(mips)));
}
pgpus.add(
new Pgpu(pgpuId, pes, new GpuGddramProvisionerSimple(gddram), new GpuBwProvisionerShared(bw)));
}
// Pgpu selection policy Pgpu选择策略
PgpuSelectionPolicy pgpuSelectionPolicy = new PgpuSelectionPolicyBreadthFirst();
// Vgpu Scheduler
VgpuScheduler vgpuScheduler = new GridVgpuSchedulerFairShare(GridVideoCardTags.NVIDIA_K1_CARD,
pgpus, pgpuSelectionPolicy);
// PCI Express Bus Bw Provisioner
VideoCardBwProvisioner videoCardBwProvisioner = new VideoCardBwProvisionerShared(
BusTags.PCI_E_3_X16_BW);
// Create a video card
VideoCard videoCard = new VideoCard(videoCardId, GridVideoCardTags.NVIDIA_K1_CARD, vgpuScheduler,
videoCardBwProvisioner);
videoCards.add(videoCard);
}
// Create a host
int hostId = GpuHostTags.DUAL_INTEL_XEON_E5_2620_V3;
// A Machine contains one or more PEs or CPUs/Cores. 一台机器包含一个或多个pe或cpu /核心。
List<Pe> peList = new ArrayList<Pe>();
// PE's MIPS power
double mips = GpuHostTags.DUAL_INTEL_XEON_E5_2620_V3_PE_MIPS;
for (int peId = 0; peId < GpuHostTags.DUAL_INTEL_XEON_E5_2620_V3_NUM_PES; peId++) {
// Create PEs and add these into a list.
peList.add(new Pe(0, new PeProvisionerSimple(mips)));
}
// Create Host with its id and list of PEs and add them to the list of machines
// 创建主机及其id和pe列表,并将它们添加到机器列表中
// host memory (MB)
int ram = GpuHostTags.DUAL_INTEL_XEON_E5_2620_V3_RAM;
// host storage
long storage = GpuHostTags.DUAL_INTEL_XEON_E5_2620_V3_STORAGE;
// host BW
int bw = GpuHostTags.DUAL_INTEL_XEON_E5_2620_V3_BW;
// Set VM Scheduler
VmScheduler vmScheduler = new VmSchedulerTimeShared(peList);
// Video Card Selection Policy
VideoCardAllocationPolicy videoCardAllocationPolicy = new VideoCardAllocationPolicyBreadthFirst(videoCards);
GpuHost newHost = new GpuHost(hostId, GpuHostTags.DUAL_INTEL_XEON_E5_2620_V3, new RamProvisionerSimple(ram),
new BwProvisionerRelaxed(bw), storage, peList, vmScheduler, videoCardAllocationPolicy);
hostList.add(newHost);
// Create a DatacenterCharacteristics object that stores the
// properties of a data center: architecture, OS, list of
// Machines, allocation policy: time- or space-shared, time zone
// and its price (G$/Pe time unit).
// system architecture
//创建一个DatacenterCharacteristics对象,用于存储
//数据中心的属性:架构,操作系统,列表
//机器,分配策略:时间或空间共享,时区
//及其价格(G$/Pe时间单位)。
//系统架构
String arch = "x86";
// operating system 操作系统
String os = "Linux";
// VM Manager 虚拟机管理者
String vmm = "Horizen";
// time zone this resource located (Tehran) 该资源所在时区(德黑兰)
double time_zone = +3.5;
// the cost of using processing in this resource 在此资源中使用处理的成本
double cost = 0.0;
// the cost of using memory in this resource 在这个资源中使用内存的代价
double costPerMem = 0.00;
// the cost of using storage in this resource 使用此资源中的存储的成本
double costPerStorage = 0.000;
// the cost of using bw in this resource 在此资源中使用bw的成本
double costPerBw = 0.0;
// we are not adding SAN devices by now 我们现在还没有添加SAN设备
LinkedList<Storage> storageList = new LinkedList<Storage>();
DatacenterCharacteristics characteristics = new DatacenterCharacteristics(arch, os, vmm, hostList, time_zone,
cost, costPerMem, costPerStorage, costPerBw);
// We need to create a Datacenter object. 创建一个数据中心对象
GpuDatacenter datacenter = null;
try {
datacenter = new GpuDatacenter(name, characteristics, new GpuVmAllocationPolicySimple(hostList),
storageList, schedulingInterval);
} catch (Exception e) {
e.printStackTrace();
}
return datacenter;
}
/**
* Create a broker.
*
* * @param name the name of the broker
*
* @return the datacenter broker
*/
private static GpuDatacenterBroker createBroker(String name) {
GpuDatacenterBroker broker = null;
try {
broker = new GpuDatacenterBroker(name);
} catch (Exception e) {
e.printStackTrace();
return null;
}
return broker;
}
/**
* Prints the GpuCloudlet objects.
*
* @paramlist
* list of GpuCloudlets 输出函数
*/
private static void printCloudletList(List<Cloudlet> gpuCloudlets) {
Log.printLine(String.join("", Collections.nCopies(100, "-")));
DecimalFormat dft = new DecimalFormat("###.##");
for (GpuCloudlet gpuCloudlet : (List<GpuCloudlet>) (List<?>) gpuCloudlets) {
// Cloudlet
AsciiTable at = new AsciiTable();
at.addRule();
at.addRow("Cloudlet ID", "Status", "Datacenter ID", "VM ID", "Time", "Start Time", "Finish Time");
at.addRule();
if (gpuCloudlet.getCloudletStatus() == Cloudlet.SUCCESS) {
at.addRow(gpuCloudlet.getCloudletId(), "SUCCESS", gpuCloudlet.getResourceId(), gpuCloudlet.getVmId(),
dft.format(gpuCloudlet.getActualCPUTime()).toString(),
dft.format(gpuCloudlet.getExecStartTime()).toString(),
dft.format(gpuCloudlet.getFinishTime()).toString());
at.addRule();
}
GpuTask gpuTask = gpuCloudlet.getGpuTask();
// Host-Device Memory Transfer
AsciiTable atMT = new AsciiTable();
atMT.addRule();
atMT.addRow("Direction", "Time", "Start Time", "End Time");
atMT.addRule();
atMT.addRow("H2D", dft.format(gpuTask.getMemoryTransferHostToDevice().getTime()).toString(),
dft.format(gpuTask.getMemoryTransferHostToDevice().startTime).toString(),
dft.format(gpuTask.getMemoryTransferHostToDevice().endTime).toString());
atMT.addRule();
// Gpu Task
at.addRow("Task ID", "Cloudlet ID", "Status", "vGPU Profile", "Time", "Start Time", "Finish Time");
at.addRule();
if (gpuTask.getTaskStatus() == GpuTask.FINISHED) {
at.addRow(gpuTask.getTaskId(), gpuTask.getCloudlet().getCloudletId(), "SUCCESS",
GridVgpuTags.getVgpuTypeString(
((GpuVm) VmList.getById(vmlist, gpuTask.getCloudlet().getVmId())).getVgpu().getType()),
dft.format(gpuTask.getActualGPUTime()).toString(),
dft.format(gpuTask.getExecStartTime()).toString(),
dft.format(gpuTask.getFinishTime()).toString());
at.addRule();
}
// Device-Host Memory Transfer
atMT.addRow("D2H", dft.format(gpuTask.getMemoryTransferDeviceToHost().getTime()).toString(),
dft.format(gpuTask.getMemoryTransferDeviceToHost().startTime).toString(),
dft.format(gpuTask.getMemoryTransferDeviceToHost().endTime).toString());
atMT.addRule();
at.getContext().setWidth(100);
atMT.getContext().setWidth(100);
Log.printLine(at.render());
Log.printLine(atMT.render());
Log.printLine(String.join("", Collections.nCopies(100, "-")));
}
}
}
对其他名词的解释
schedulingInterval
# 调度间隔
GpuTask # 表示在一个Vgpu中执行的进程 面向底层
Cloudlet # 表示为一个应用程序 其length表示主机的任务量 注意无论是CloudSim还是GpuCloudSim等扩展的仿真器都是