package experiments.simpat2014.models.article; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; import schedframe.events.scheduling.SchedulingEvent; import schedframe.resources.CoolEmAllResourceType; import schedframe.resources.ResourceStatus; import schedframe.resources.StandardResourceType; import schedframe.resources.computing.ComputingResource; import schedframe.resources.computing.Core; import schedframe.resources.computing.Node; import schedframe.resources.computing.Processor; import schedframe.resources.computing.Rack; import schedframe.resources.computing.coolemall.ComputeBox1; import schedframe.resources.computing.coolemall.NodeGroup; import schedframe.resources.computing.profiles.energy.ResourceEvent; import schedframe.resources.computing.profiles.energy.ResourceEventType; import schedframe.resources.computing.profiles.energy.airthroughput.CustomAirflowStateName; import schedframe.resources.computing.profiles.energy.power.PState; import schedframe.resources.devices.Device; import schedframe.resources.devices.Fan; import schedframe.resources.units.ProcessingElements; import schedframe.resources.units.ResourceUnit; import schedframe.resources.units.ResourceUnitName; import schedframe.resources.units.StandardResourceUnitName; import schedframe.scheduling.manager.resources.ClusterResourceManager; import schedframe.scheduling.manager.resources.ResourceManager; import schedframe.scheduling.manager.tasks.JobRegistry; import schedframe.scheduling.plan.SchedulingPlanInterface; import schedframe.scheduling.plan.impl.SchedulingPlan; import schedframe.scheduling.plugin.ModuleList; import schedframe.scheduling.queue.TaskQueue; import schedframe.scheduling.queue.TaskQueueList; import schedframe.scheduling.tasks.TaskInterface; import simulator.DataCenterWorkloadSimulator; import test.Node_Fan_Mapping; import eduni.simjava.Sim_system; import example.energy.coolemall.CoolEmAllTestbedMeasurements; import example.localplugin.BaseLocalSchedulingPlugin; import experiments.simpat2014.EnvironmentConditions; import gridsim.dcworms.DCWormsTags; public class FCFSBF_RandomPluginPowerCapping extends BaseLocalSchedulingPlugin { private Random rand; private Map powerCapsLevels; private Map powerUpgradesLevels; private Map currentFrequencyLevels; public FCFSBF_RandomPluginPowerCapping () { rand = new Random(5); currentFrequencyLevels = new HashMap(); powerCapsLevels = new HashMap(); powerUpgradesLevels = new HashMap(); } public SchedulingPlanInterface schedule(SchedulingEvent event, TaskQueueList queues, JobRegistry jobRegistry, ResourceManager resManager, ModuleList modules) { ClusterResourceManager resourceManager = (ClusterResourceManager) resManager; SchedulingPlan plan = new SchedulingPlan(); // choose the events types to serve. // Different actions for different events are possible. switch (event.getType()) { case TIMER: System.out.println("##" + Sim_system.clock()); DataCenterWorkloadSimulator.getEventManager().sendToResources(StandardResourceType.Processor, 0.0, new ResourceEvent(ResourceEventType.TIMER, null)); //DataCenterWorkloadSimulator.getEventManager().sendToAllSchedulers(EnvironmentConditions.SYSTEM_UDPATE_INTERVAL, DCWormsTags.TIMER, "Test"); break; case START_TASK_EXECUTION: case TASK_FINISHED: //case TIMER: // our tasks are placed only in first queue (see // BaseLocalSchedulingPlugin.placeJobsInQueues() method) TaskQueue q = queues.get(0); // check all tasks in queue for (int i = 0; i < q.size(); i++) { TaskInterface task = q.get(i); // if status of the tasks in READY if (task.getStatus() == DCWormsTags.READY) { if(resourceManager.getResourcesByTypeWithStatus(StandardResourceType.Core, ResourceStatus.FREE).size() == 0) break; Map choosenResources = chooseResourcesForExecution(resourceManager, task); if (choosenResources != null) { addToSchedulingPlan(plan, task, choosenResources); } } } break; case RESOURCE_POWER_LIMIT_EXCEEDED: powerCap(resManager, event.getSource().toString()); break; case RESOURCE_TEMPERATURE_LIMIT_EXCEEDED: manageFans(resourceManager.getResourceByName(event.getSource())); break; } return plan; } private void manageFans(ComputingResource cr ){ //System.out.println("tuning fans"); double temp = cr.getThermalInterface().getRecentTemperature().getValue(); double prevTemp; if(cr.getThermalInterface().getTemperatureHistory().size() == 1) prevTemp = temp; else { prevTemp = cr.getThermalInterface().getTemperatureHistory().get(cr.getThermalInterface().getTemperatureHistory().size() - 2).getValue(); } //System.out.println(prevTemp+ "; " + temp); boolean getingHotter = prevTemp < temp; boolean getingColder = prevTemp > temp; Node n = (Node) cr.getParent(); for(Device d: n.getParent().getResourceCharacteristic().getDevices()){ //System.out.println(d.getName() + "; " + n.getName()); if(Integer.valueOf(d.getName().split("_")[1]).intValue() == Integer.valueOf(n.getName().split("_")[1]).intValue() || Integer.valueOf(d.getName().split("_")[1]).intValue() == Integer.valueOf(n.getName().split("_")[1]).intValue() - EnvironmentConditions.NODES_IN_A_ROW){ Fan f = (Fan) d; int speed; try{ speed= Integer.valueOf(f.getAirflowInterface().getAirflowState().getLabel().split("_")[1]).intValue(); } catch(Exception e){ speed = 0; } if(getingHotter){ if(temp > EnvironmentConditions.tempLevelLow2Medium && temp < EnvironmentConditions.tempLevelMedium2High){ if(speed < 60){ //System.out.println("+++++++++ low 2 medium"); f.getAirflowInterface().setAirflowState(new CustomAirflowStateName("ON_60")); } } else if (temp > EnvironmentConditions.tempLevelMedium2High && temp < EnvironmentConditions.tempLevelHigh2Max) { if(speed < 80){ //System.out.println("++++++++medium 2 high"); f.getAirflowInterface().setAirflowState(new CustomAirflowStateName("ON_80")); } } else if (temp > EnvironmentConditions.tempLevelHigh2Max) { if(speed < 100){ //System.out.println("++++++++high 2 max"); f.getAirflowInterface().setAirflowState(new CustomAirflowStateName("ON_100")); } } } else if (getingColder){ if(temp > EnvironmentConditions.tempLevelHigh2Medium && temp < EnvironmentConditions.tempLevelMax2High){ if(speed == 100){ //System.out.println("-------- max 2 high"); f.getAirflowInterface().setAirflowState(new CustomAirflowStateName("ON_80")); } } else if(temp > EnvironmentConditions.tempLevelMedium2Low && temp < EnvironmentConditions.tempLevelHigh2Medium){ if(speed >= 80){ //System.out.println("-------- high 2 medium"); f.getAirflowInterface().setAirflowState(new CustomAirflowStateName("ON_60")); } } else if (temp < EnvironmentConditions.tempLevelMedium2Low) { if(speed >= 60){ //System.out.println("-------- medium 2 low"); f.getAirflowInterface().setAirflowState(new CustomAirflowStateName("ON_30")); } } } } } } private Map chooseResourcesForExecution( ClusterResourceManager resourceManager, TaskInterface task) { Map map = new HashMap(); List nodes = resourceManager.getNodes(); List avNodes = filterNodes(nodes, task); if(avNodes.size() == 0) return null; Node node = randomNode(avNodes); int cpuRequest; try { cpuRequest = Double.valueOf(task.getCpuCntRequest()).intValue(); } catch (NoSuchFieldException e) { cpuRequest = 0; } if (cpuRequest != 0) { List choosenResources = new ArrayList(); List cores = node.getCores(); for (int i = 0; i < cores.size() && cpuRequest > 0; i++) { if (cores.get(i).getStatus() == ResourceStatus.FREE) { choosenResources.add(cores.get(i)); cpuRequest--; } } if (cpuRequest > 0) { return null; } //choosenResources.add(node.getProcessors().get(0)); ProcessingElements pe = new ProcessingElements(); pe.addAll(choosenResources); map.put(StandardResourceUnitName.PE, pe); return map; } return null; } private List filterNodes(List nodes, TaskInterface task){ List filteredNodes = new ArrayList(); int cpuRequest; try { cpuRequest = Double.valueOf(task.getCpuCntRequest()).intValue(); } catch (NoSuchFieldException e) { cpuRequest = 0; } for (Node node : nodes) { if (cpuRequest != 0) { List cores = node.getCores(); if (cores.size() < cpuRequest) { if(cores.size() == 0){ if(node.getProcessors().size() < cpuRequest) continue; } } int freeCores = 0; for(Core core: cores){ if(core.getStatus() == ResourceStatus.FREE) freeCores++; } if(freeCores < cpuRequest) continue; filteredNodes.add(node); } } return filteredNodes; } private Node randomNode(List nodes){ return nodes.get(rand.nextInt(nodes.size())); } private void powerCap(ResourceManager resManager, String resName){ ComputingResource compRes = resManager.getResourceByName(resName); //for(ComputingResource compRes: resManager.getResourcesOfType(CoolEmAllResourceType.NodeGroup)){ if(!powerCapsLevels.containsKey(compRes.getFullName()) || !powerUpgradesLevels.containsKey(compRes.getFullName())){ loadThresholds(compRes); } double powerConsumption = compRes.getPowerInterface().getRecentPowerUsage().getValue(); //System.out.println(compRes.getFullName() + " current: " + powerConsumption); if(powerConsumption > powerCapsLevels.get(compRes.getFullName())){ NodeGroup nodeGroup = (NodeGroup) compRes; List processors = nodeGroup.getProcessors(); double currentFrequencyLevel = 0; if(currentFrequencyLevels.get(compRes.getFullName()) != null){ currentFrequencyLevel = currentFrequencyLevels.get(compRes.getFullName()); } else { currentFrequencyLevel = processors.get(0).getPowerInterface().getLowestPState().getFrequency(); } boolean overThreshold = true; boolean canDoBetter = true; while(overThreshold && canDoBetter){ //System.out.println(compRes.getFullName() + " - downgrading"); int procNumberWithoutChange = 0; boolean improvement = false; //System.out.println(compRes.getFullName() + "; currentFrequencyLevel: " + currentFrequencyLevel); for (Processor proc: processors){ PState currPState = proc.getPowerInterface().getPState(); //System.out.println(proc.getFullName() + " - checking"); if(currPState.getFrequency() <= currentFrequencyLevel && proc.getFreeCores().size() != proc.getCores().size()){ //System.out.println("operating same level"); procNumberWithoutChange++; continue; } if (proc.getFreeCores().size() == proc.getCores().size()){ //System.out.println("free"); procNumberWithoutChange++; continue; } double lowerFrequency = proc.getPowerInterface().getHighestPState().getFrequency(); for(String pStateName: proc.getPowerInterface().getSupportedPStates().keySet()){ PState pState = proc.getPowerInterface().getSupportedPStates().get(pStateName); if(pState.getFrequency() > lowerFrequency && pState.getFrequency() < currPState.getFrequency()){ lowerFrequency = pState.getFrequency(); } } //System.out.println(proc.getFullName() + "; lower frequency: " + lowerFrequency); if(lowerFrequency < currentFrequencyLevel){ //System.out.println(compRes.getFullName() + " - changing current frequency level"); currentFrequencyLevels.put(compRes.getFullName(), lowerFrequency); currentFrequencyLevel = currentFrequencyLevels.get(compRes.getFullName()); } if(lowerFrequency != currPState.getFrequency()) { //System.out.println(proc.getFullName() + " - lowering frequency"); proc.getPowerInterface().setFrequency(lowerFrequency); Node n = proc.getNode(); for(Device device: n.getParent().getResourceCharacteristic().getDevices()){ if(device.getType().equals(StandardResourceType.Fan) || device.getType().equals(StandardResourceType.Inlet) | device.getType().equals(StandardResourceType.Outlet)){ Fan fan = (Fan) device; if(fan.getChilledResources().contains(n.getFullName())){ fan.getAirflowInterface().setAirflowState(new CustomAirflowStateName("ON_30")); } } } improvement = true; } if(lowerFrequency == proc.getPowerInterface().getHighestPState().getFrequency()){ canDoBetter = false; } else { canDoBetter = true; } if(compRes.getPowerInterface().getRecentPowerUsage().getValue() <= powerCapsLevels.get(compRes.getFullName())){ overThreshold = false; break; } } if(procNumberWithoutChange == processors.size() || improvement == false){ //System.out.println(compRes.getFullName() + " - failed to improve"); double nextFrequencyLevel = processors.get(0).getPowerInterface().getHighestPState().getFrequency(); for (Processor proc: processors){ for(String pStateName: proc.getPowerInterface().getSupportedPStates().keySet()){ PState pState = proc.getPowerInterface().getSupportedPStates().get(pStateName); if(pState.getFrequency() > nextFrequencyLevel && pState.getFrequency() < currentFrequencyLevel){ nextFrequencyLevel = pState.getFrequency(); } } } //System.out.println(compRes.getFullName() + "; nextFrequencyLevel: " + nextFrequencyLevel); currentFrequencyLevels.put(compRes.getFullName(), nextFrequencyLevel); currentFrequencyLevel = currentFrequencyLevels.get(compRes.getFullName()); if(currentFrequencyLevel == processors.get(0).getPowerInterface().getHighestPState().getFrequency()){ canDoBetter = false; } procNumberWithoutChange = 0; } } } else if (powerConsumption < powerUpgradesLevels.get(compRes.getFullName())) { NodeGroup nodeGroup = (NodeGroup) compRes; List processors = nodeGroup.getProcessors(); double currentFrequencyLevel = 0; if(currentFrequencyLevels.get(compRes.getFullName()) != null){ currentFrequencyLevel = currentFrequencyLevels.get(compRes.getFullName()); } else { currentFrequencyLevel = processors.get(0).getPowerInterface().getLowestPState().getFrequency(); } boolean overThreshold = true; boolean canDoBetter = true; while(overThreshold && canDoBetter){ //System.out.println(compRes.getFullName() + " - downgrading"); int procNumberWithoutChange = 0; boolean improvement = false; //System.out.println(compRes.getFullName() + "; currentFrequencyLevel: " + currentFrequencyLevel); for (Processor proc: processors){ PState currPState = proc.getPowerInterface().getPState(); //System.out.println(proc.getFullName() + " - checking"); if(currPState.getFrequency() >= currentFrequencyLevel && proc.getFreeCores().size() != proc.getCores().size()){ //System.out.println("operating same level"); procNumberWithoutChange++; continue; } if (proc.getFreeCores().size() == proc.getCores().size()){ //System.out.println("free"); procNumberWithoutChange++; continue; } double higherFrequency = proc.getPowerInterface().getLowestPState().getFrequency(); for(String pStateName: proc.getPowerInterface().getSupportedPStates().keySet()){ PState pState = proc.getPowerInterface().getSupportedPStates().get(pStateName); if(pState.getFrequency() < higherFrequency && pState.getFrequency() > currPState.getFrequency()){ higherFrequency = pState.getFrequency(); } } //System.out.println(proc.getFullName() + "; lower frequency: " + lowerFrequency); if(higherFrequency > currentFrequencyLevel){ //System.out.println(compRes.getFullName() + " - changing current frequency level"); currentFrequencyLevels.put(compRes.getFullName(), higherFrequency); currentFrequencyLevel = currentFrequencyLevels.get(compRes.getFullName()); } if(higherFrequency != currPState.getFrequency()) { //System.out.println(proc.getFullName() + " - lowering frequency"); proc.getPowerInterface().setFrequency(higherFrequency); Node n = proc.getNode(); for(Device device: n.getParent().getResourceCharacteristic().getDevices()){ if(device.getType().equals(StandardResourceType.Fan) || device.getType().equals(StandardResourceType.Inlet) | device.getType().equals(StandardResourceType.Outlet)){ Fan fan = (Fan) device; if(fan.getChilledResources().contains(n.getFullName())){ fan.getAirflowInterface().setAirflowState(new CustomAirflowStateName("ON_30")); } } } improvement = true; } if(higherFrequency == proc.getPowerInterface().getLowestPState().getFrequency()){ canDoBetter = false; } else { canDoBetter = true; } if(compRes.getPowerInterface().getRecentPowerUsage().getValue() >= powerCapsLevels.get(compRes.getFullName())){ overThreshold = false; break; } } if(procNumberWithoutChange == processors.size() || improvement == false){ //System.out.println(compRes.getFullName() + " - failed to improve"); double nextFrequencyLevel = processors.get(0).getPowerInterface().getLowestPState().getFrequency(); for (Processor proc: processors){ for(String pStateName: proc.getPowerInterface().getSupportedPStates().keySet()){ PState pState = proc.getPowerInterface().getSupportedPStates().get(pStateName); if(pState.getFrequency() < nextFrequencyLevel && pState.getFrequency() > currentFrequencyLevel){ nextFrequencyLevel = pState.getFrequency(); } } } //System.out.println(compRes.getFullName() + "; nextFrequencyLevel: " + nextFrequencyLevel); currentFrequencyLevels.put(compRes.getFullName(), nextFrequencyLevel); currentFrequencyLevel = currentFrequencyLevels.get(compRes.getFullName()); if(currentFrequencyLevel == processors.get(0).getPowerInterface().getLowestPState().getFrequency()){ canDoBetter = false; } procNumberWithoutChange = 0; } } } //} //if(Sim_system.clock() > 1000 && Sim_system.clock() < 1100 || Sim_system.clock() > 3400) //System.out.println(currentFrequencyLevels); } private void loadThresholds(ComputingResource compResource){ double pcLevel = 0; double puLevel = 0; /*NodeGroup ng = (NodeGroup) compResource; for(Processor proc: ng.getProcessors()){ PState highestPState = proc.getPowerInterface().getHighestPState(); PState secondHighestPState = proc.getPowerInterface().getLowestPState(); for(String pStateName: proc.getPowerInterface().getSupportedPStates().keySet()){ PState pState = proc.getPowerInterface().getSupportedPStates().get(pStateName); if(pState.getFrequency() < secondHighestPState.getFrequency() && pState.getFrequency() > highestPState.getFrequency()){ secondHighestPState = pState; } } double maxMinPowerUsage = 0; double powerUsage = 0; for(Double load: highestPState.getLoadPowerUsage().keySet()){ powerUsage = highestPState.getLoadPowerUsage().get(load); if(powerUsage > maxMinPowerUsage){ maxMinPowerUsage= powerUsage; } } pcLevel = pcLevel + maxMinPowerUsage; maxMinPowerUsage = 0; powerUsage = 0; for(Double load: secondHighestPState.getLoadPowerUsage().keySet()){ powerUsage = secondHighestPState.getLoadPowerUsage().get(load); if(powerUsage > maxMinPowerUsage){ maxMinPowerUsage= powerUsage; } } puLevel = puLevel + maxMinPowerUsage; } puLevel = (pcLevel * pcLevel / puLevel); */ pcLevel = EnvironmentConditions.powerCapLevel; puLevel = EnvironmentConditions.powerUpgradeLevel; powerCapsLevels.put(compResource.getFullName(), pcLevel); powerUpgradesLevels.put(compResource.getFullName(), puLevel); } }