aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Erickson <jerickso@cs.unc.edu>2012-10-29 12:18:48 -0400
committerJeremy Erickson <jerickso@cs.unc.edu>2012-10-29 14:10:32 -0400
commit107da1b6a3840b0e39b436ea51686aa381d27b90 (patch)
tree92391d2791c6c858ac426c532111fa507cf7f17c
parent37dbd04e4f9d8956cf4be1c196e282760aa37011 (diff)
Added arbitrary-precision arithmetic to native module
-rw-r--r--native/include/edf/gel_pl.h30
-rw-r--r--native/src/edf/gel_pl.cpp147
-rw-r--r--schedcat/sched/edf/gel_pl.py69
3 files changed, 152 insertions, 94 deletions
diff --git a/native/include/edf/gel_pl.h b/native/include/edf/gel_pl.h
index 4093d95..1127d50 100644
--- a/native/include/edf/gel_pl.h
+++ b/native/include/edf/gel_pl.h
@@ -13,17 +13,21 @@ class GELPl
13 int no_cpus; 13 int no_cpus;
14 const TaskSet& tasks; 14 const TaskSet& tasks;
15 int rounds; 15 int rounds;
16 std::vector<double> S_i; 16 std::vector<fractional_t> S_i;
17 std::vector<double> G_i; 17 std::vector<fractional_t> G_i;
18 18
19 // For faster lookups, to avoid too many conversions. 19 // For faster lookups, to avoid too many conversions.
20 std::vector<double> utilizations; 20 std::vector<fractional_t> utilizations;
21 21
22 double compute_exact_s(double S, const std::vector<double>& Y_ints); 22 void compute_exact_s(const fractional_t& S,
23 double compute_binsearch_s(double S, const std::vector<double>& Y_ints); 23 const std::vector<fractional_t>& Y_ints,
24 fractional_t& s);
25 void compute_binsearch_s(const fractional_t& S,
26 const std::vector<fractional_t>& Y_ints,
27 fractional_t& s);
24 28
25 inline double compute_M(double s, double S, 29 inline bool M_lt_0(const fractional_t& s, const fractional_t& S,
26 const std::vector<double>& Y_ints); 30 const std::vector<fractional_t>& Y_ints);
27 31
28 // These are basically just structs that override operator< to allow 32 // These are basically just structs that override operator< to allow
29 // sort algorithms to work. 33 // sort algorithms to work.
@@ -31,8 +35,8 @@ class GELPl
31 public: 35 public:
32 unsigned int old_task; 36 unsigned int old_task;
33 unsigned int new_task; 37 unsigned int new_task;
34 double location; 38 fractional_t location;
35 double old_task_utilization; 39 fractional_t old_task_utilization;
36 40
37 bool operator<(const ReplacementType& other) const { 41 bool operator<(const ReplacementType& other) const {
38 return (location < other.location) 42 return (location < other.location)
@@ -44,7 +48,7 @@ class GELPl
44 class TaggedValue { 48 class TaggedValue {
45 public: 49 public:
46 unsigned int task; 50 unsigned int task;
47 double value; 51 fractional_t value;
48 52
49 //Order is reversed - we are going to want the largest, rather than the 53 //Order is reversed - we are going to want the largest, rather than the
50 //smallest, values. 54 //smallest, values.
@@ -68,12 +72,14 @@ class GELPl
68 return bounds[index]; 72 return bounds[index];
69 } 73 }
70 74
75 // Converted to double for the sake of Python
71 double get_Si(unsigned int index) { 76 double get_Si(unsigned int index) {
72 return S_i[index]; 77 return S_i[index].get_d();
73 } 78 }
74 79
80 // Converted to double for the sake of Python
75 double get_Gi(unsigned int index) { 81 double get_Gi(unsigned int index) {
76 return G_i[index]; 82 return G_i[index].get_d();
77 } 83 }
78}; 84};
79 85
diff --git a/native/src/edf/gel_pl.cpp b/native/src/edf/gel_pl.cpp
index 53ae575..f0f9303 100644
--- a/native/src/edf/gel_pl.cpp
+++ b/native/src/edf/gel_pl.cpp
@@ -6,8 +6,10 @@
6#include <limits> 6#include <limits>
7#include <algorithm> 7#include <algorithm>
8#include <cmath> 8#include <cmath>
9#include <iostream>
9 10
10static bool reversed_order(double first, double second) { 11static bool reversed_order(const fractional_t& first,
12 const fractional_t& second) {
11 return second < first; 13 return second < first;
12} 14}
13 15
@@ -16,8 +18,8 @@ GELPl::GELPl(Scheduler sched, unsigned int num_processors, const TaskSet& ts,
16:no_cpus(num_processors), tasks(ts), rounds(num_rounds) 18:no_cpus(num_processors), tasks(ts), rounds(num_rounds)
17{ 19{
18 std::vector<unsigned long> pps; 20 std::vector<unsigned long> pps;
19 double S; 21 fractional_t S = 0;
20 std::vector<double> Y_ints; 22 std::vector<fractional_t> Y_ints;
21 23
22 int task_count = tasks.get_task_count(); 24 int task_count = tasks.get_task_count();
23 // Reserve capacity in all vectors to minimize allocation costs. 25 // Reserve capacity in all vectors to minimize allocation costs.
@@ -29,8 +31,8 @@ GELPl::GELPl(Scheduler sched, unsigned int num_processors, const TaskSet& ts,
29 // For faster lookups 31 // For faster lookups
30 utilizations.reserve(task_count); 32 utilizations.reserve(task_count);
31 for (int i = 0; i < task_count; i++) { 33 for (int i = 0; i < task_count; i++) {
32 utilizations.push_back(double(tasks[i].get_wcet()) 34 utilizations.push_back(tasks[i].get_wcet());
33 / double(tasks[i].get_period())); 35 utilizations[i] /= tasks[i].get_period();
34 } 36 }
35 37
36 unsigned long min_pp = std::numeric_limits<unsigned long>::max(); 38 unsigned long min_pp = std::numeric_limits<unsigned long>::max();
@@ -50,36 +52,60 @@ GELPl::GELPl(Scheduler sched, unsigned int num_processors, const TaskSet& ts,
50 52
51 // Reduce to compute minimum. Also compute Y intercepts, S_i values, and 53 // Reduce to compute minimum. Also compute Y intercepts, S_i values, and
52 // S. 54 // S.
53 S = 0.0;
54 for (int i = 0; i < task_count; i++) { 55 for (int i = 0; i < task_count; i++) {
55 pps[i] -= min_pp; 56 pps[i] -= min_pp;
56 const Task& task = tasks[i]; 57 const Task& task = tasks[i];
57 double wcet = double(task.get_wcet()); 58 unsigned long wcet = task.get_wcet();
58 double period = double(task.get_period()); 59 unsigned long period = task.get_period();
59 S_i[i] = std::max(0.0, wcet * (1.0 - double(pps[i])/ period)); 60 S_i.push_back(pps[i]);
60 S += S_i[i]; 61 fractional_t& S_i_i = S_i[i];
61 Y_ints.push_back((0.0 - wcet/no_cpus) * (wcet / period) 62 S_i_i *= -1;
62 + task.get_wcet() - S_i[i]); 63 S_i_i /= period;
64 S_i_i += 1;
65 S_i_i *= wcet;
66 if (S_i_i < 0) {
67 S_i_i = 0;
68 }
69 S += S_i_i;
70 Y_ints.push_back(wcet);
71 fractional_t& Y_ints_i = Y_ints[i];
72 Y_ints_i *= -1;
73 Y_ints_i /= no_cpus;
74 Y_ints_i *= utilizations[i];
75 Y_ints_i += wcet;
76 Y_ints_i -= S_i_i;
63 } 77 }
64 78
65 double s; 79 fractional_t s;
66 if (rounds == 0) { 80 if (rounds == 0) {
67 s = compute_exact_s(S, Y_ints); 81 compute_exact_s(S, Y_ints, s);
68 } 82 }
69 else { 83 else {
70 s = compute_binsearch_s(S, Y_ints); 84 compute_binsearch_s(S, Y_ints, s);
71 } 85 }
72 86
73 for (int i = 0; i < task_count; i++) { 87 for (int i = 0; i < task_count; i++) {
88 fractional_t x_i = s;
89 fractional_t x_comp = tasks[i].get_wcet();
90 x_comp /= no_cpus;
91 x_i -= x_comp;
92 // Compute ceiling
93 integral_t xi_ceil = x_i.get_num();
94 mpz_cdiv_q(xi_ceil.get_mpz_t(),
95 x_i.get_num().get_mpz_t(),
96 x_i.get_den().get_mpz_t());
74 bounds.push_back(pps[i] 97 bounds.push_back(pps[i]
75 + tasks[i].get_wcet() 98 + tasks[i].get_wcet()
76 + (unsigned long)std::ceil( 99 + xi_ceil.get_ui());
77 s - (double(tasks[i].get_wcet() / double(no_cpus))))); 100 G_i.push_back(s);
78 G_i.push_back(Y_ints[i] + s * utilizations[i]); 101 G_i[i] *= utilizations[i];
102 G_i[i] += Y_ints[i];
79 } 103 }
80} 104}
81 105
82double GELPl::compute_exact_s(double S, const std::vector<double>& Y_ints) { 106void GELPl::compute_exact_s(const fractional_t& S,
107 const std::vector<fractional_t>& Y_ints,
108 fractional_t& s) {
83 int task_count = tasks.get_task_count(); 109 int task_count = tasks.get_task_count();
84 110
85 std::vector<ReplacementType> replacements; 111 std::vector<ReplacementType> replacements;
@@ -88,19 +114,22 @@ double GELPl::compute_exact_s(double S, const std::vector<double>& Y_ints) {
88 // We can ignore parallel and identical lines - either don't 114 // We can ignore parallel and identical lines - either don't
89 // intersect or we don't care which is picked. 115 // intersect or we don't care which is picked.
90 if (utilizations[i] != utilizations[j]) { 116 if (utilizations[i] != utilizations[j]) {
91 double intersect = (Y_ints[j] - Y_ints[i]) 117 fractional_t intersect_den = utilizations[i];
92 / (utilizations[i] - utilizations[j]); 118 intersect_den -= utilizations[j];