Commit 1b8a538a by Michael Schmid

latest changes, used on paper

parent 8054de06
......@@ -6,9 +6,12 @@ import mvd.jester.model.DagTask;
import mvd.jester.model.SystemManager;
import mvd.jester.model.SystemManager.DagTaskBuilder;
import mvd.jester.tests.AbstractTest;
import mvd.jester.tests.DongLiu;
import mvd.jester.tests.FonsecaNelis;
import mvd.jester.tests.JiangYi;
import mvd.jester.tests.SchmidMottok;
import mvd.jester.tests.Tester;
import mvd.jester.tests.UeterAgrawal;
import mvd.jester.tests.TypeFunction.UnknownStructure;
......@@ -19,66 +22,92 @@ import mvd.jester.tests.TypeFunction.UnknownStructure;
public class App {
public static void main(String[] args) {
{
SystemManager<DagTaskBuilder> manager = new SystemManager<>(DagTaskBuilder.class);
SystemManager<DagTaskBuilder> manager =
new SystemManager<>(DagTaskBuilder.class);
manager.setNumberOfProcessors(8);
TestEnvironment te = new TestEnvironment();
List<AbstractTest<DagTask>> tests = te.registerTests(Arrays.asList(
/* new SchmidMottok(new KnownStructure(), manager), */
new SchmidMottok(new UnknownStructure(), manager),
// new Tester(new UnknownStructure(), manager),
new SchmidMottok(new UnknownStructure(), manager), //
// new Tester(new UnknownStructure(),manager),
// new MelaniButtazzo(manager),,
new FonsecaNelis(manager), //
// new FonsecaNelis(manager), //
// new DongLiu(manager), //
new UeterAgrawal(manager), //
new JiangYi(manager)//
));
te.varyRenyiUtilization(manager, tests, 500);
te.varyRenyiUtilization(manager, tests, 200);
}
{
SystemManager<DagTaskBuilder> manager = new SystemManager<>(DagTaskBuilder.class);
manager.setNumberOfProcessors(8);
SystemManager<DagTaskBuilder> manager =
new SystemManager<>(DagTaskBuilder.class);
manager.setNumberOfProcessors(16);
TestEnvironment te = new TestEnvironment();
List<AbstractTest<DagTask>> tests = te.registerTests(Arrays.asList(
/* new SchmidMottok(new KnownStructure(), manager), */
new SchmidMottok(new UnknownStructure(), manager),
// new Tester(new UnknownStructure(), manager),
new SchmidMottok(new UnknownStructure(), manager), //
// new Tester(new UnknownStructure(),manager),
// new MelaniButtazzo(manager),,
new FonsecaNelis(manager), //
// new FonsecaNelis(manager), //
// new DongLiu(manager), //
new UeterAgrawal(manager), //
new JiangYi(manager)//
));
te.varyPropability(manager, tests, 500);
te.varyRenyiUtilization(manager, tests, 200);
}
{
SystemManager<DagTaskBuilder> manager = new SystemManager<>(DagTaskBuilder.class);
manager.setNumberOfProcessors(8);
SystemManager<DagTaskBuilder> manager =
new SystemManager<>(DagTaskBuilder.class);
manager.setNumberOfProcessors(32);
TestEnvironment te = new TestEnvironment();
List<AbstractTest<DagTask>> tests = te.registerTests(Arrays.asList( //
// new SchmidMottok(new KnownStructure(), manager), //
List<AbstractTest<DagTask>> tests = te.registerTests(Arrays.asList(
new SchmidMottok(new UnknownStructure(), manager), //
// new Tester(new UnknownStructure(), manager), //
// new MelaniButtazzo(manager), //
new FonsecaNelis(manager), //
new JiangYi(manager)));
// new Tester(new UnknownStructure(),manager),
// new MelaniButtazzo(manager),,
// new FonsecaNelis(manager), //
// new DongLiu(manager), //
new UeterAgrawal(manager), //
new JiangYi(manager)//
));
te.varyNumberOfProcessors(manager, tests, 500);
te.varyRenyiUtilization(manager, tests, 200);
}
{
SystemManager<DagTaskBuilder> manager = new SystemManager<>(DagTaskBuilder.class);
manager.setNumberOfProcessors(8);
TestEnvironment te = new TestEnvironment();
// {
// SystemManager<DagTaskBuilder> manager = new
// SystemManager<>(DagTaskBuilder.class);
// manager.setNumberOfProcessors(8);
// TestEnvironment te = new TestEnvironment();
List<AbstractTest<DagTask>> tests = te.registerTests(Arrays.asList( //
// new SchmidMottok(new KnownStructure(), manager), //
new SchmidMottok(new UnknownStructure(), manager), //
// new Tester(new UnknownStructure(), manager), //
// new MelaniButtazzo(manager), //
new FonsecaNelis(manager), //
new JiangYi(manager)));
// List<AbstractTest<DagTask>> tests = te.registerTests(Arrays.asList( //
// // new SchmidMottok(new KnownStructure(), manager), //
// new SchmidMottok(new UnknownStructure(), manager), //
// // new Tester(new UnknownStructure(), manager), //
// // new MelaniButtazzo(manager), //
// new FonsecaNelis(manager), //
// new UeterAgrawal(manager), //
// new JiangYi(manager)));
te.varyNumberOfTasks(manager, tests, 500);
}
// te.varyNumberOfProcessors(manager, tests, 200);
// }
// {
// SystemManager<DagTaskBuilder> manager = new
// SystemManager<>(DagTaskBuilder.class);
// manager.setNumberOfProcessors(8);
// TestEnvironment te = new TestEnvironment();
// List<AbstractTest<DagTask>> tests = te.registerTests(Arrays.asList( //
// // new SchmidMottok(new KnownStructure(), manager), //
// new SchmidMottok(new UnknownStructure(), manager), //
// // new Tester(new UnknownStructure(), manager), //
// // new MelaniButtazzo(manager), //
// new FonsecaNelis(manager), //
// new UeterAgrawal(manager), //
// new JiangYi(manager)));
// te.varyNumberOfTasks(manager, tests, 200);
// }
}
}
......@@ -35,12 +35,12 @@ public class ResultLogger {
public <T extends Task> void logLine(final double utilization,
final Map<AbstractTest<T>, Long> results) {
final Map<AbstractTest<T>, Long> results, long numberOfTestedTasksets) {
final Appendable out = new StringBuilder();
try {
out.append("" + utilization);
for (final Entry<AbstractTest<T>, Long> rc : results.entrySet()) {
final long numberOfFeasibleTasks = rc.getValue();
final long numberOfFeasibleTasks = rc.getValue() / ( numberOfTestedTasksets / 100);
out.append("\t" + numberOfFeasibleTasks);
}
} catch (final Exception e) {
......
......@@ -112,14 +112,14 @@ public class TestEnvironment {
final List<AbstractTest<DagTask>> abstractTestInstances,
final long numberOfTaskSetsPerStep) {
long checkedTasksets = 0;
final long numberOfTaskSets = 8 * numberOfTaskSetsPerStep;
final long numberOfTaskSets = 5 * numberOfTaskSetsPerStep;
final ResultLogger resultLogger = new ResultLogger("numberOfProcessors");
final Map<AbstractTest<DagTask>, Long> resultMap = new LinkedHashMap<>();
abstractTestInstances.forEach(t -> resultMap.put(t, (long) 0));
resultLogger.logHeader(resultMap, "NoOfProcessors");
for (long numberOfProcessors = 2; numberOfProcessors <= 16; numberOfProcessors += 2) {
for (long numberOfProcessors = 2; numberOfProcessors <= 32; numberOfProcessors *= 2) {
manager.setNumberOfProcessors(numberOfProcessors);
resultMap.replaceAll((k, v) -> (long) 0);
for (int i = 0; i < numberOfTaskSetsPerStep; ++i) {
......@@ -142,7 +142,7 @@ public class TestEnvironment {
}
checkedTasksets++;
}
resultLogger.logLine(numberOfProcessors, resultMap);
resultLogger.logLine(numberOfProcessors, resultMap, numberOfTaskSetsPerStep);
resultLogger.newLine();
}
System.out.println("");
......@@ -184,7 +184,7 @@ public class TestEnvironment {
}
checkedTasksets++;
}
resultLogger.logLine(numberOfTasks, resultMap);
resultLogger.logLine(numberOfTasks, resultMap, numberOfTaskSetsPerStep);
resultLogger.newLine();
}
System.out.println("");
......@@ -224,7 +224,7 @@ public class TestEnvironment {
}
checkedTasksets++;
}
resultLogger.logLine(util, resultMap);
resultLogger.logLine(util, resultMap, numberOfTaskSetsPerUtil);
resultLogger.newLine();
}
System.out.println("");
......@@ -266,7 +266,7 @@ public class TestEnvironment {
}
checkedTasksets++;
}
resultLogger.logLine(util, resultMap);
resultLogger.logLine(util / numberOfProcessors, resultMap, numberOfTaskSetsPerUtil);
resultLogger.newLine();
}
System.out.println("");
......@@ -306,7 +306,7 @@ public class TestEnvironment {
}
checkedTasksets++;
}
resultLogger.logLine(p_add, resultMap);
resultLogger.logLine(p_add, resultMap, numberOfTaskSetsPerStep);
resultLogger.newLine();
}
System.out.println("");
......
......@@ -20,6 +20,15 @@ public class DagTask extends Task {
}
public DagTask(final DirectedAcyclicGraph<Job, DefaultEdge> jobDag, final long period,
final long deadline, final long numberOfThreads) {
super(period, deadline, DagUtils.calculateWorkload(jobDag),
DagUtils.calculateCriticalPath(jobDag), numberOfThreads);
this.jobDag = jobDag;
this.workloadDistribution =
DagUtils.calculateWorkloadDistribution(this.jobDag, this.criticalPath);
}
public DagTask(final DirectedAcyclicGraph<Job, DefaultEdge> jobDag, final long period,
final Set<Segment> workloadDistribution, final long numberOfThreads) {
super(period, period, DagUtils.calculateWorkload(jobDag),
DagUtils.calculateCriticalPath(jobDag), numberOfThreads);
......
package mvd.jester.model;
import java.util.HashSet;
import java.util.Set;
public class LightTask extends Task {
private final Set<Segment> segments;
public LightTask(long period, long deadline, long workload) {
super(period, deadline, workload, workload, 1);
segments = new HashSet<>();
segments.add(new Segment(workload, 1));
}
@Override
public long getMaximumParallelism() {
return 1;
}
@Override
public Set<Segment> getWorkloadDistribution() {
return segments;
}
}
......@@ -216,17 +216,24 @@ public class SystemManager<T extends Builder> implements SystemManagerInterface
} else {
final double remainingUtilization = totalUtilization - currentUtilization;
final long period = (long) Math.ceil(task.getWorkload() / remainingUtilization);
if (period >= task.getCriticalPath()) {
long numberOfThreads =
LongMath.divide(task.getWorkload() - task.getCriticalPath(),
period - task.getCriticalPath(), RoundingMode.CEILING);
final long criticalPath = task.getCriticalPath();
if (period >= criticalPath) {
final long deadline = randomNumberInRange(
criticalPath + (period - criticalPath) / 4, period); // TODO:
// deadline =
// period?
// final long deadline = period;
long numberOfThreads = LongMath.divide(task.getWorkload() - criticalPath,
deadline - criticalPath, RoundingMode.CEILING);
if (numberOfThreads == 0) {
numberOfThreads = 1;
}
final DagTask modifiedTask =
new DagTask(task.getJobDag(), period, numberOfThreads);
new DagTask(task.getJobDag(), period, deadline, numberOfThreads);
taskSet.add(modifiedTask);
break;
}
......@@ -324,15 +331,21 @@ public class SystemManager<T extends Builder> implements SystemManagerInterface
final long workload = DagUtils.calculateWorkload(jobDag);
final long criticalPath = DagUtils.calculateCriticalPath(jobDag);
final long period = randomRenyiPeriod(workload, criticalPath, totalUtilization);
final long deadline =
randomNumberInRange(criticalPath + (period - criticalPath) / 4, period); // TODO:
// oder
// period?
// final long deadline = period;
final long numberOfThreads = LongMath.divide(workload - criticalPath,
period - criticalPath, RoundingMode.CEILING);
deadline - criticalPath, RoundingMode.CEILING);
if (numberOfThreads == 0) {
return new DagTask(jobDag, period, 1);
return new DagTask(jobDag, period, deadline, 1);
}
return new DagTask(jobDag, period, numberOfThreads);
return new DagTask(jobDag, period, deadline, numberOfThreads);
}
private long randomRenyiPeriod(final long workload, final long criticalPath,
......
package mvd.jester.priority;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import mvd.jester.model.Task;
import mvd.jester.simulator.AbstractSimulator;
import mvd.jester.simulator.internals.TaskContextInterface;
import mvd.jester.tests.AbstractTest;
public class DeadlineMonotonic implements PriorityManager {
final static Set<Class<? extends AbstractTest<? extends Task>>> abstractTests =
new HashSet<>(Arrays.asList(mvd.jester.tests.MaiaBertogna.class,
mvd.jester.tests.SchmidMottok.class));
final static Set<Class<? extends AbstractSimulator>> abstractSimulators =
new HashSet<>(Arrays.asList(mvd.jester.simulator.ParallelSynchronous.class,
mvd.jester.simulator.DynamicForkJoin.class));
/**
* Compare the priority of two tasks according to the Rate Monotonic policy
*
* @param t1 The first task
* @param t2 The second task
* @return 0 if both tasks have the same priority, negative number if the first task has a
* higher priority, positive number if the second task has a higher priority
*/
@Override
public int compare(Task t1, Task t2) {
return Long.compare(t1.getDeadline(), t2.getDeadline());
}
@Override
public int compare(TaskContextInterface t1, TaskContextInterface t2) {
return Long.compare(t1.getTask().getDeadline(), t2.getTask().getDeadline());
}
@Override
public boolean hasTest(AbstractTest<? extends Task> abstractTest) {
return abstractTests.contains(abstractTest.getClass());
}
@Override
public boolean hasTest(Class<? extends AbstractTest<? extends Task>> abstractTestClass) {
return abstractTests.contains(abstractTestClass);
}
@Override
public boolean hasSimulator(AbstractSimulator abstractSimulator) {
return abstractSimulators.contains(abstractSimulator.getClass());
}
@Override
public boolean hasSimulator(Class<? extends AbstractSimulator> abstractSimulatorClass) {
return abstractSimulators.contains(abstractSimulatorClass);
}
@Override
public String getName() {
return "DM";
}
}
package mvd.jester.tests;
import mvd.jester.info.SchedulingInfo;
import mvd.jester.info.SchedulingInfo.Feasiblity;
import mvd.jester.model.DagTask;
import mvd.jester.model.SortedTaskSet;
import mvd.jester.model.SystemManagerInterface;
import mvd.jester.priority.EarliestDeadlineFirst;
import mvd.jester.priority.PriorityManager;
public class DongLiu extends AbstractTest<DagTask> {
private final EarliestDeadlineFirst priorityManager;
public DongLiu(SystemManagerInterface manager) {
super(manager);
this.priorityManager = new EarliestDeadlineFirst();
}
@Override
public SchedulingInfo runSchedulabilityCheck(SortedTaskSet<DagTask> tasks) {
final long numberOfProcessors = manager.getNumberOfProcessors();
for (DagTask task : tasks) {
double sumOfWorkloads = 0;
for (DagTask t : tasks) {
sumOfWorkloads += getAverageWorkload(t, task);
}
final double cpUtilization = (double) task.getCriticalPath() / task.getPeriod();
if (!(sumOfWorkloads <= numberOfProcessors
- ((numberOfProcessors - 1) * cpUtilization))) {
return new SchedulingInfo(Feasiblity.FAILED);
}
}
return new SchedulingInfo(Feasiblity.SUCCEEDED);
}
private double getAverageWorkload(DagTask t, DagTask task) {
final double cpUtilization = (double) task.getCriticalPath() / task.getPeriod();
final double taskUtilization = t.getUtilization();
if (cpUtilization >= taskUtilization) {
return taskUtilization;
} else {
return taskUtilization + ((double) t.getWorkload() - cpUtilization * t.getPeriod())
/ (task.getPeriod());
}
}
@Override
public PriorityManager getPriorityManager() {
return priorityManager;
}
@Override
public String getName() {
return "DongLiu";
}
}
......@@ -25,6 +25,7 @@ import mvd.jester.model.SystemManagerInterface;
import mvd.jester.model.Task;
import mvd.jester.model.TreeJob;
import mvd.jester.utils.DagUtils;
import mvd.jester.priority.DeadlineMonotonic;
import mvd.jester.priority.PriorityManager;
import mvd.jester.priority.RateMonotonic;
import mvd.jester.utils.BinaryDecompositionTree;
......@@ -40,7 +41,7 @@ public class FonsecaNelis extends AbstractTest<DagTask> {
public FonsecaNelis(final SystemManagerInterface manager) {
super(manager);
this.responseTimes = new HashMap<>();
this.priorityManager = new RateMonotonic();
this.priorityManager = new DeadlineMonotonic();
this.carryOutSegments = new HashMap<>();
}
......@@ -153,7 +154,7 @@ public class FonsecaNelis extends AbstractTest<DagTask> {
previousResponseTime = responseTime;
double taskInterference = 0;
for (final DagTask t : tasks) {
if (t.getPeriod() < task.getPeriod()) {
if (priorityManager.compare(t, task) < 0) {
taskInterference += getTaskInterference(t, responseTime);
}
}
......
......@@ -34,7 +34,7 @@ public class JiangYi extends AbstractTest<DagTask> {
Set<Task> lightTasks = new HashSet<>();
for (DagTask t : tasks) {
if (t.getUtilization() < 1) {
if (t.getDensity() < 1) {
lightTasks.add(t);
} else {
heavyTasks.add(t);
......@@ -68,10 +68,10 @@ public class JiangYi extends AbstractTest<DagTask> {
Collections.sort(taskList, (a, b) -> Double.compare(b.getDensity(), a.getDensity()));
List<Double> bins = new ArrayList<>();
for (int i = 0; i < numberOfprocessors; ++i) {
bins.add((double) 0);
}
Iterator<Task> taskIterator = taskList.iterator();
while (taskIterator.hasNext()) {
Collections.sort(bins);
......
......@@ -11,6 +11,7 @@ import mvd.jester.model.DagTask;
import mvd.jester.model.SortedTaskSet;
import mvd.jester.model.SystemManagerInterface;
import mvd.jester.model.Task;
import mvd.jester.priority.DeadlineMonotonic;
import mvd.jester.priority.PriorityManager;
import mvd.jester.priority.RateMonotonic;
......@@ -26,7 +27,7 @@ public class SchmidMottok extends AbstractTest<DagTask> {
public SchmidMottok(TypeFunction structure, final SystemManagerInterface manager) {
super(manager);
this.responseTimes = new HashMap<>();
this.priorityManager = new RateMonotonic();
this.priorityManager = new DeadlineMonotonic();
this.structure = structure;
}
......@@ -56,10 +57,11 @@ public class SchmidMottok extends AbstractTest<DagTask> {
long numberOfProcessors = manager.getNumberOfProcessors();
long occupiedProcessors = 0;
for (DagTask t : tasks) {
if (occupiedProcessors >= numberOfProcessors) {
t.setNumberOfThreads(numberOfProcessors);
if (occupiedProcessors + t.getNumberOfThreads() <= numberOfProcessors) {
occupiedProcessors += t.getNumberOfThreads();
} else {
occupiedProcessors += t.getNumberOfThreads();
t.setNumberOfThreads(numberOfProcessors);
}
}
}
......@@ -72,7 +74,7 @@ public class SchmidMottok extends AbstractTest<DagTask> {
long occupiedProcessors = 0;
for (final DagTask t : tasks) {
if (t.getPeriod() < task.getPeriod()) {
if (priorityManager.compare(t, task) < 0) {
final long numberOfThreads = structure.getNumberOfThreads(t);
occupiedProcessors += numberOfThreads;
}
......@@ -88,7 +90,7 @@ public class SchmidMottok extends AbstractTest<DagTask> {
double taskInterference = 0;
for (final DagTask t : tasks) {
if (t.getPeriod() < task.getPeriod()) {
if (priorityManager.compare(t, task) < 0) {
final long numberOfThreads = structure.getNumberOfThreads(t);
for (int p = 0; p < numberOfThreads; ++p) {
taskInterference +=
......@@ -104,17 +106,17 @@ public class SchmidMottok extends AbstractTest<DagTask> {
long totalInterference = (long) Math.floor(taskInterference + selfInterference);
responseTime = minimumWcet + totalInterference;
} while (previousResponseTime != responseTime);
if (occupiedProcessors < numberOfProcessors) {
long workloadAmongRemainingProcessors =
LongMath.divide(task.getWorkload() - task.getCriticalPath(),
numberOfProcessors - occupiedProcessors, RoundingMode.FLOOR);
totalInterference =
Math.min(totalInterference, workloadAmongRemainingProcessors);
responseTime =
Math.min(responseTime, workloadAmongRemainingProcessors + minimumWcet);
}
responseTime = minimumWcet + totalInterference;
} while (previousResponseTime != responseTime);
return responseTime;
}
}
......
package mvd.jester.tests;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.math.LongMath;
import mvd.jester.info.SchedulingInfo;
import mvd.jester.info.TerminationInfo;
import mvd.jester.info.SchedulingInfo.Feasiblity;
import mvd.jester.model.DagTask;
import mvd.jester.model.LightTask;
import mvd.jester.model.SortedTaskSet;
import mvd.jester.model.SystemManagerInterface;
import mvd.jester.model.Task;
import mvd.jester.priority.DeadlineMonotonic;
import mvd.jester.priority.PriorityManager;
import mvd.jester.priority.RateMonotonic;
public class Tester extends AbstractTest<DagTask> {
private final Map<Task, TerminationInfo> responseTimes;
private final PriorityManager priorityManager;
private final TypeFunction structure;
public Tester(TypeFunction structure, final SystemManagerInterface manager) {
super(manager);
this.responseTimes = new HashMap<>();
this.priorityManager = new RateMonotonic();
this.structure = structure;
this.priorityManager = new DeadlineMonotonic();
}
@Override
public SchedulingInfo runSchedulabilityCheck(SortedTaskSet<DagTask> tasks) {
responseTimes.clear();
assignNumberOfThreads(tasks);
for (final DagTask t : tasks) {
final long responseTime = calculateResponseTime(tasks, t);
responseTimes.put(t, new TerminationInfo(t.getDeadline(), responseTime));
}
public SchedulingInfo runSchedulabilityCheck(final SortedTaskSet<DagTask> tasks) {
reassignNumberOfThreads(tasks);
return new SchedulingInfo(responseTimes.values());
}
List<Double> processorBins = new ArrayList<>();
@Override
public PriorityManager getPriorityManager() {
return priorityManager;
for (int i = 0; i < manager.getNumberOfProcessors(); ++i) {
processorBins.add((double) 0);
}
private void assignNumberOfThreads(Set<DagTask> tasks) {
long occupiedProcessors = 0;
long numberOfProcessors = manager.getNumberOfProcessors();
for (DagTask t : tasks) {
long workload = t.getWorkload();
long criticalPath = t.getCriticalPath();
long period = t.getPeriod();
if (period == criticalPath) {
t.setNumberOfThreads(1);
} else if (occupiedProcessors >= numberOfProcessors) {
t.setNumberOfThreads(numberOfProcessors);
nextTask: for (DagTask t : tasks) {
final long minimumNumberOfThreads = t.getNumberOfThreads();
for (long numberOfThreads = minimumNumberOfThreads; numberOfThreads < manager
.getNumberOfProcessors(); ++numberOfThreads) {
List<Double> copiedProcessorBins = copyBins(processorBins);
Collections.sort(copiedProcessorBins);
final long criticalPath = t.getCriticalPath();
final long workload = t.getWorkload();
final long processorWorkload =
(long) Math.ceil(copiedProcessorBins.get(0) * t.getDeadline());
final long workloadPerThread =
LongMath.divide(workload, numberOfThreads, RoundingMode.CEILING);
final long threadWorkload = Math.max(workloadPerThread, criticalPath);
if (threadWorkload + processorWorkload <= t.getDeadline()) {
copiedProcessorBins.set(0,
copiedProcessorBins.get(0) + (double) (threadWorkload) / t.getPeriod());
for (int m = 0; m < numberOfThreads - 1; ++m) {
Collections.sort(copiedProcessorBins);
final long nextProcessorWorkload =
(long) Math.ceil(copiedProcessorBins.get(0) * t.getDeadline());
if (threadWorkload + nextProcessorWorkload <= t.getDeadline()) {
copiedProcessorBins.set(0, copiedProcessorBins.get(0)
+ (double) threadWorkload / t.getPeriod());
} else {
final long numberOfThreads = LongMath.divide(workload - criticalPath,
period - criticalPath, RoundingMode.CEILING);
t.setNumberOfThreads(numberOfThreads);
occupiedProcessors += numberOfThreads;
return new SchedulingInfo(Feasiblity.FAILED);
}
}
}
@Override
public String getName() {
return "Tester_" + structure.getType();
processorBins = copiedProcessorBins;
continue nextTask;
}
private long calculateResponseTime(final Set<DagTask> tasks, final DagTask task) {
final long minimumWcet = task.getCriticalPath();
long responseTime = minimumWcet;
long previousResponseTime = 0;
final long numberOfProcessors = manager.getNumberOfProcessors();
long occupiedProcessors = 0;
for (final DagTask t : tasks) {
if (t.getPeriod() < task.getPeriod()) {
final long numberOfThreads = structure.getNumberOfThreads(t);
occupiedProcessors += numberOfThreads;
}
return new SchedulingInfo(Feasiblity.FAILED);
}
final double selfInterference = structure.getSelfInterference(task);
if (occupiedProcessors + structure.getNumberOfThreads(task) <= numberOfProcessors) {
return minimumWcet + (long) Math.floor(selfInterference);
} else {
do {
previousResponseTime = responseTime;
double taskInterference = 0;
for (final DagTask t : tasks) {
if (t.getPeriod() < task.getPeriod()) {
final long numberOfThreads = structure.getNumberOfThreads(t);
for (int p = 0; p < numberOfThreads; ++p) {
taskInterference +=
Math.min(
structure.getTaskInterference(t, responseTimes,
responseTime, p + 1),
responseTime - minimumWcet + 1);
return new SchedulingInfo(Feasiblity.SUCCEEDED);
}
private void reassignNumberOfThreads(Set<DagTask> tasks) {
for (DagTask t : tasks) {
final long numberOfThreads = LongMath.divide(t.getWorkload() - t.getCriticalPath(),
t.getDeadline() - t.getCriticalPath(), RoundingMode.CEILING);
t.setNumberOfThreads(numberOfThreads);
}
}
taskInterference /= numberOfProcessors;
private List<Double> copyBins(List<Double> bins) {
List<Double> copiedBins = new ArrayList<>();
long totalInterference = (long) Math.floor(taskInterference + selfInterference);
if (occupiedProcessors < numberOfProcessors) {
long workloadAmongRemainingProcessors =
LongMath.divide(task.getWorkload() - task.getCriticalPath(),
numberOfProcessors - occupiedProcessors, RoundingMode.FLOOR);
totalInterference =
Math.min(totalInterference, workloadAmongRemainingProcessors);
for (Double b : bins) {
copiedBins.add(b.doubleValue());
}
responseTime = minimumWcet + totalInterference;
} while (previousResponseTime != responseTime);
return copiedBins;
}
return responseTime;
@Override
public PriorityManager getPriorityManager() {
return priorityManager;
}
@Override
public String getName() {
return "Tester";
}
}
package mvd.jester.tests;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.math.LongMath;
import mvd.jester.info.SchedulingInfo;
import mvd.jester.info.SchedulingInfo.Feasiblity;
import mvd.jester.model.DagTask;
import mvd.jester.model.LightTask;
import mvd.jester.model.SortedTaskSet;
import mvd.jester.model.SystemManagerInterface;
import mvd.jester.model.Task;
import mvd.jester.priority.EarliestDeadlineFirst;
import mvd.jester.priority.PriorityManager;
public class UeterAgrawal extends AbstractTest<DagTask> {
private final EarliestDeadlineFirst priorityManager;
private final Map<DagTask, Double> stretchRatios;
public UeterAgrawal(SystemManagerInterface manager) {
super(manager);
this.priorityManager = new EarliestDeadlineFirst();
this.stretchRatios = new HashMap<>();
}
@Override
public SchedulingInfo runSchedulabilityCheck(SortedTaskSet<DagTask> tasks) {
stretchRatios.clear();
assignThreadsAndStretchRatio(tasks);
List<Double> bins = new ArrayList<>();
for (int i = 0; i < manager.getNumberOfProcessors(); ++i) {
bins.add((double) 0);
}
for (DagTask t : tasks) {
if (t.getNumberOfThreads() == 1) { // Light task
if (!bestFitBinPackingOfTask(bins, t)) {
return new SchedulingInfo(Feasiblity.FAILED);
}
} else { // heavy task
boolean failure = true;
long numberOfServers = 0;
List<Double> binsWithTask = copyBins(bins);
final List<Task> listOfServerTasks = new ArrayList<>();
listOfServerTasks.add(t);
while (numberOfServers <= checkNumberOfServers(t)) {
if (!binPackingOfServers(binsWithTask, listOfServerTasks)) {
binsWithTask = copyBins(bins);
numberOfServers += 1;
listOfServerTasks.clear();
for (int l = 0; l < numberOfServers; ++l) {
long reservationBudget = (long) Math.ceil((double) t.getWorkload()
/ numberOfServers
+ (1 - (double) 1 / numberOfServers) * t.getCriticalPath());
listOfServerTasks.add(new LightTask(t.getPeriod(), t.getDeadline(),
reservationBudget));
}
} else {
failure = false;
bins = binsWithTask;
break;
}
}
if (failure) {
return new SchedulingInfo(Feasiblity.FAILED);
}
}
}
return new SchedulingInfo(Feasiblity.SUCCEEDED);
}
private List<Double> copyBins(List<Double> bins) {
List<Double> copiedBins = new ArrayList<>();
for (Double b : bins) {
copiedBins.add(b.doubleValue());
}
return copiedBins;
}
private long checkNumberOfServers(DagTask task) {
final long criticalPath = task.getCriticalPath();
final long workload = task.getWorkload();
final double strechRatio = stretchRatios.get(task);
final long first = LongMath.divide(workload, criticalPath, RoundingMode.CEILING);
final long second = (long) Math
.ceil(((double) workload - criticalPath) / (criticalPath * (strechRatio - 1)));
// TODO: include fucking boundaries
final long max = Math.max(first, second);
return max;
}
private boolean binPackingOfServers(List<Double> bins, List<Task> tasks) {
for (Task t : tasks) {
if (!bestFitBinPackingOfTask(bins, t)) {
return false;
}
}
return true;
}
private boolean bestFitBinPackingOfTask(List<Double> bins, Task task) {
int bestFit = 0; // No one at first
for (int b = 0; b < bins.size(); ++b) {
if (bins.get(b) + task.getDensity() <= 1) {
double currentBin = bins.get(b);
double bestBin = bins.get(bestFit);
if (currentBin + task.getDensity() > bestBin + task.getDensity() || bestBin + task.getDensity() > 1) {
bestFit = b;
}
}
}
if (bins.get(bestFit) + task.getDensity() <= 1) {
bins.set(bestFit, bins.get(bestFit) + task.getDensity());
return true;
}
return false;
}
private boolean firstFitBinPackingOfTask(List<Double> bins, Task task) {
Collections.sort(bins);
Collections.reverse(bins);
for (int b = 0; b < bins.size(); ++b) {
if (bins.get(b) + task.getDensity() <= 1) {
bins.set(b, bins.get(b) + task.getDensity());
return true;
}
}
return false;
}
private boolean worstFitBinPackingOfTask(List<Double> bins, Task task) {
Collections.sort(bins);
if (bins.get(0) + task.getDensity() <= 1) {
bins.set(0, bins.get(0) + task.getDensity());
return true;
} else {
return false;
}
}
private void assignThreadsAndStretchRatio(Set<DagTask> tasks) {
for (DagTask t : tasks) {
final long criticalPath = t.getCriticalPath();
final long workload = t.getWorkload();
long numberOfThreads = LongMath.divide(workload - criticalPath,
t.getDeadline() - criticalPath, RoundingMode.CEILING);
if (numberOfThreads == 0) {
numberOfThreads = 1;
}
t.setNumberOfThreads(numberOfThreads);
final double stretchRatio =
1 + ((double) workload - criticalPath) / (numberOfThreads * criticalPath);
stretchRatios.put(t, stretchRatio);
}
}
@Override
public PriorityManager getPriorityManager() {
return priorityManager;
}
@Override
public String getName() {
return "UeterAgrawal";
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment