package test.freqscaling; 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.exceptions.ResourceException; 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.coolemall.ComputeBox1; 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.devices.PhysicalResource; 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 test.Node_Fan_Mapping; import example.localplugin.BaseLocalSchedulingPlugin; import gridsim.dcworms.DCWormsTags; public class CB2_FCFS_Random_SP extends BaseLocalSchedulingPlugin { private Random rand; public static String mode; private int MAX_THRESHOLD = 450; private int MIN_THRESHOLD = 400; private Map currentFrequencyLevels; public CB2_FCFS_Random_SP () { rand = new Random(47); Node_Fan_Mapping.init(); currentFrequencyLevels = new HashMap(); mode = ""; } 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 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); break; } return plan; } @SuppressWarnings("unchecked") 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)); if(true) { if(cores.get(i).getProcessor().getPowerInterface().getPState().equals(cores.get(i).getProcessor().getPowerInterface().getHighestPState())) cores.get(i).getProcessor().getPowerInterface().setPState(cores.get(i).getProcessor().getPowerInterface().getLowestPState().getName()); } Node n = cores.get(i).getProcessor().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("2")); } } } 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){ for(ComputingResource compRes: resManager.getResourcesOfType(StandardResourceType.Rack)){ loadThresholds(compRes); double powerConsumption = compRes.getPowerInterface().getRecentPowerUsage().getValue(); //System.out.println(compRes.getFullName() + " current: " + powerConsumption); if(powerConsumption > MAX_THRESHOLD){ mode = compRes.getFullName(); ComputeBox1 cb1 = (ComputeBox1) compRes; List processors = cb1.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("2")); } } } improvement = true; } if(lowerFrequency == proc.getPowerInterface().getHighestPState().getFrequency()){ canDoBetter = false; } else { canDoBetter = true; } if(compRes.getPowerInterface().getRecentPowerUsage().getValue() <= MAX_THRESHOLD){ 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 < MIN_THRESHOLD) { ComputeBox1 cb1 = (ComputeBox1) compRes; List processors = cb1.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("2")); } } } improvement = true; } if(higherFrequency == proc.getPowerInterface().getLowestPState().getFrequency()){ canDoBetter = false; } else { canDoBetter = true; } if(compRes.getPowerInterface().getRecentPowerUsage().getValue() >= MAX_THRESHOLD){ 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; } } } mode = ""; } } private void loadThresholds(PhysicalResource resource){ MAX_THRESHOLD =450; MIN_THRESHOLD = 400; } }