aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2012-12-09 11:39:41 -0500
committerBjoern Brandenburg <bbb@mpi-sws.org>2013-02-12 06:55:16 -0500
commit308ff37a60a61e158bfe108bfcea0bf3b71e942d (patch)
treebb8abf906bdd5823aeefa3c89668d38c6f1bc3d8
parentadfef1cb9a8960690fb85cc0b99e8fe266e173eb (diff)
Add LP-based blocking analysis for FMLP+
-rw-r--r--native/Makefile2
-rw-r--r--native/include/lp_analysis.h12
-rw-r--r--native/src/blocking/linprog/lp_fmlp.cpp286
-rw-r--r--schedcat/locking/bounds.py13
4 files changed, 307 insertions, 6 deletions
diff --git a/native/Makefile b/native/Makefile
index 2df9893..6f1abe2 100644
--- a/native/Makefile
+++ b/native/Makefile
@@ -118,7 +118,7 @@ ALL = testmain _sched.so _locking.so _sim.so
118 118
119# Compile LP-based code only if we have a solver. 119# Compile LP-based code only if we have a solver.
120ifneq ($(CPLEX_PATH)$(GLPK_PATH),) 120ifneq ($(CPLEX_PATH)$(GLPK_PATH),)
121LP_OBJ = lp_common.o io.o lp_dflp.o lp_dpcp.o lp_mpcp.o 121LP_OBJ = lp_common.o io.o lp_dflp.o lp_dpcp.o lp_mpcp.o lp_fmlp.o
122 122
123ifneq ($(CPLEX_PATH),) 123ifneq ($(CPLEX_PATH),)
124LP_OBJ += cplex.o cpx.o 124LP_OBJ += cplex.o cpx.o
diff --git a/native/include/lp_analysis.h b/native/include/lp_analysis.h
index 182eff1..998eeb5 100644
--- a/native/include/lp_analysis.h
+++ b/native/include/lp_analysis.h
@@ -3,12 +3,14 @@
3 3
4#include "sharedres_types.h" 4#include "sharedres_types.h"
5 5
6extern BlockingBounds* lp_dpcp_bounds(const ResourceSharingInfo& info, 6BlockingBounds* lp_dpcp_bounds(const ResourceSharingInfo& info,
7 const ResourceLocality& locality, bool use_RTA = true); 7 const ResourceLocality& locality, bool use_RTA = true);
8 8
9extern BlockingBounds* lp_dflp_bounds(const ResourceSharingInfo& info, 9BlockingBounds* lp_dflp_bounds(const ResourceSharingInfo& info,
10 const ResourceLocality& locality); 10 const ResourceLocality& locality);
11 11
12extern BlockingBounds* lp_mpcp_bounds(const ResourceSharingInfo& info); 12BlockingBounds* lp_mpcp_bounds(const ResourceSharingInfo& info);
13
14BlockingBounds* lp_part_fmlp_bounds(const ResourceSharingInfo& info);
13 15
14#endif /* LP_ANALYSYS_H_ */ 16#endif /* LP_ANALYSYS_H_ */
diff --git a/native/src/blocking/linprog/lp_fmlp.cpp b/native/src/blocking/linprog/lp_fmlp.cpp
new file mode 100644
index 0000000..75e2186
--- /dev/null
+++ b/native/src/blocking/linprog/lp_fmlp.cpp
@@ -0,0 +1,286 @@
1#include <iostream>
2#include <set>
3#include <algorithm>
4
5#include "lp_common.h"
6#include "blocking.h"
7#include "stl-hashmap.h"
8
9#include "cpu_time.h"
10
11typedef hashmap<unsigned int, unsigned int> BlockingLimits;
12
13// Constraint 14
14static void add_fifo_cluster_constraints(
15 VarMapper& vars,
16 const ResourceSharingInfo& info,
17 const TaskInfo& ti,
18 LinearProgram& lp)
19{
20 foreach_remote_task(info.get_tasks(), ti, tx)
21 {
22 unsigned int t = tx->get_id();
23
24 // compute direct blocking opportunities, not counting Tx
25 BlockingLimits per_resource_remote;
26
27 foreach(ti.get_requests(), req)
28 per_resource_remote[req->get_resource_id()] = 0;
29
30 foreach_local_task_except(info.get_tasks(), *tx, ty)
31 {
32 foreach(ty->get_requests(), req)
33 {
34 unsigned int u = req->get_resource_id();
35 if (per_resource_remote.find(u) !=
36 per_resource_remote.end())
37 per_resource_remote[u] += req->get_max_num_requests(ti.get_response());
38 }
39 }
40
41 unsigned int total_limit = 0;
42 foreach(ti.get_requests(), req)
43 {
44 unsigned int u = req->get_resource_id();
45 total_limit += std::min(req->get_num_requests(),
46 per_resource_remote[u]);
47 }
48
49 LinearExpression *exp = new LinearExpression();
50
51 foreach(tx->get_requests(), request)
52 {
53 unsigned int q = request->get_resource_id();
54
55 foreach_request_instance(*request, ti, v)
56 {
57 unsigned int var_id;
58 var_id = vars.lookup(t, q, v, BLOCKING_INDIRECT);
59 exp->add_var(var_id);
60 }
61 }
62
63 lp.add_inequality(exp, total_limit);
64 }
65}
66
67// Constraint 13
68static void add_total_fifo_constraints(
69 VarMapper& vars,
70 const ResourceSharingInfo& info,
71 const TaskInfo& ti,
72 LinearProgram& lp,
73 BlockingLimits &per_cluster_counts)
74{
75
76 unsigned int total_num_requests = 0;
77
78 foreach(ti.get_requests(), req)
79 total_num_requests += req->get_num_requests();
80
81 foreach_task_except(info.get_tasks(), ti, tx)
82 {
83 unsigned int t = tx->get_id();
84
85 LinearExpression *exp = new LinearExpression();
86
87 //for all requests accessed by tx
88 foreach(tx->get_requests(), request)
89 {
90 unsigned int q = request->get_resource_id();
91
92 foreach_request_instance(*request, ti, v)
93 {
94 unsigned int var_id;
95 var_id = vars.lookup(t, q, v, BLOCKING_DIRECT);
96 exp->add_var(var_id);
97 var_id = vars.lookup(t, q, v, BLOCKING_INDIRECT);
98 exp->add_var(var_id);
99 }
100 }
101
102 lp.add_inequality(exp, per_cluster_counts[tx->get_cluster()]);
103 }
104}
105
106// Constraint 12
107static void add_fifo_resource_constraints(
108 VarMapper& vars,
109 const ResourceSharingInfo& info,
110 const TaskInfo& ti,
111 LinearProgram& lp)
112{
113 BlockingLimits per_resource_counts;
114
115 foreach(ti.get_requests(), req)
116 per_resource_counts[req->get_resource_id()] = req->get_num_requests();
117
118 foreach_task_except(info.get_tasks(), ti, tx)
119 {
120 unsigned int t = tx->get_id();
121 //for all requests accessed by tx
122 foreach(tx->get_requests(), request)
123 {
124 unsigned int q = request->get_resource_id();
125 LinearExpression *exp = new LinearExpression();
126
127 foreach_request_instance(*request, ti, v)
128 {
129 unsigned int var_id;
130 var_id = vars.lookup(t, q, v, BLOCKING_DIRECT);
131 exp->add_var(var_id);
132 }
133
134 lp.add_inequality(exp, per_resource_counts[q]);
135 }
136 }
137}
138
139static BlockingLimits count_blocking_opportunities(
140 const ResourceSharingInfo &info,
141 const TaskInfo& ti)
142{
143 BlockingLimits per_cluster_counts;
144
145 foreach_task_except(info.get_tasks(), ti, tx)
146 {
147 unsigned int c = tx->get_cluster();
148
149 if (per_cluster_counts.find(c) == per_cluster_counts.end())
150 {
151 // compute direct blocking opportunities on Tx's cluster
152 BlockingLimits per_resource_remote;
153
154 foreach(ti.get_requests(), req)
155 per_resource_remote[req->get_resource_id()] = 0;
156
157 foreach_local_task(info.get_tasks(), *tx, ty)
158 {
159 foreach(ty->get_requests(), req)
160 {
161 unsigned int u = req->get_resource_id();
162 if (per_resource_remote.find(u) !=
163 per_resource_remote.end())
164 per_resource_remote[u] += req->get_max_num_requests(ti.get_response());
165 }
166 }
167
168 per_cluster_counts[c] = 0;
169 foreach(ti.get_requests(), req)
170 {
171 unsigned int u = req->get_resource_id();
172 per_cluster_counts[c] += std::min(req->get_num_requests(),
173 per_resource_remote[u]);
174 }
175 }
176 }
177
178 return per_cluster_counts;
179}
180
181static void add_fmlp_constraints(
182 VarMapper& vars,
183 const ResourceSharingInfo& info,
184 const TaskInfo& ti,
185 LinearProgram& lp)
186{
187 // Constraint 1
188 add_mutex_constraints(vars, info, ti, lp);
189 // Constraint 9
190 add_local_higher_priority_constraints_shm(vars, info, ti, lp);
191 // Constraint 10
192 add_topology_constraints_shm(vars, info, ti, lp);
193 // Constraint 11
194 add_local_lower_priority_constraints_shm(vars, info, ti, lp);
195
196 BlockingLimits per_cluster_counts;
197 per_cluster_counts = count_blocking_opportunities(info, ti);
198
199 // Constraint 12
200 add_fifo_resource_constraints(vars, info, ti, lp);
201 // Constraint 13
202 add_total_fifo_constraints(vars, info, ti, lp, per_cluster_counts);
203 // Constraint 14
204 add_fifo_cluster_constraints(vars, info, ti, lp);
205}
206
207static void apply_fmlp_bounds_for_task(
208 unsigned int i,
209 BlockingBounds& bounds,
210 const ResourceSharingInfo& info)
211{
212 LinearProgram lp;
213 VarMapper vars;
214 const TaskInfo& ti = info.get_tasks()[i];
215 LinearExpression *local_obj = new LinearExpression();
216
217#if DEBUG_LP_OVERHEADS >= 2
218 static DEFINE_CPU_CLOCK(model_gen_cost);
219 static DEFINE_CPU_CLOCK(solver_cost);
220
221 std::cout << "---- " << __FUNCTION__ << " ----" << std::endl;
222
223 model_gen_cost.start();
224#endif
225
226 set_blocking_objective_part_shm(vars, info, ti, lp, local_obj);
227 vars.seal();
228
229 add_fmlp_constraints(vars, info, ti, lp);
230
231#if DEBUG_LP_OVERHEADS >= 2
232 model_gen_cost.stop();
233 std::cout << model_gen_cost << std::endl;
234 solver_cost.start();
235#endif
236
237 Solution *sol = linprog_solve(lp, vars.get_num_vars());
238
239#if DEBUG_LP_OVERHEADS >= 2
240 solver_cost.stop();
241 std::cout << solver_cost << std::endl;
242#endif
243 assert(sol != NULL);
244
245 Interference total, remote, local;
246
247 total.total_length = sol->evaluate(*lp.get_objective());
248 local.total_length = sol->evaluate(*local_obj);
249 remote.total_length = total.total_length - local.total_length;
250
251 bounds[i] = total;
252 bounds.set_remote_blocking(i, remote);
253 bounds.set_local_blocking(i, local);
254
255 delete local_obj;
256 delete sol;
257}
258
259
260static BlockingBounds* _lp_fmlp_bounds(const ResourceSharingInfo& info)
261{
262 BlockingBounds* results = new BlockingBounds(info);
263
264 for (unsigned int i = 0; i < info.get_tasks().size(); i++)
265 apply_fmlp_bounds_for_task(i, *results, info);
266
267 return results;
268}
269
270BlockingBounds* lp_part_fmlp_bounds(const ResourceSharingInfo& info)
271{
272#if DEBUG_LP_OVERHEADS >= 1
273 static DEFINE_CPU_CLOCK(cpu_costs);
274
275 cpu_costs.start();
276#endif
277
278 BlockingBounds *results = _lp_fmlp_bounds(info);
279
280#if DEBUG_LP_OVERHEADS >= 1
281 cpu_costs.stop();
282 std::cout << cpu_costs << std::endl;
283#endif
284
285 return results;
286}
diff --git a/schedcat/locking/bounds.py b/schedcat/locking/bounds.py
index dc20241..9e7601c 100644
--- a/schedcat/locking/bounds.py
+++ b/schedcat/locking/bounds.py
@@ -234,3 +234,16 @@ def apply_lp_mpcp_bounds(all_tasks):
234 # all blocking, including local blocking 234 # all blocking, including local blocking
235 t.blocked = res.get_blocking_term(i) 235 t.blocked = res.get_blocking_term(i)
236 t.locally_blocked = res.get_local_blocking(i) 236 t.locally_blocked = res.get_local_blocking(i)
237
238def apply_lp_part_fmlp_bounds(all_tasks):
239 # LP-based analysis of the partitioned, preemptive FMLP+
240 model = get_cpp_model(all_tasks)
241 res = lp_cpp.lp_part_fmlp_bounds(model)
242
243 for i,t in enumerate(all_tasks):
244 # remote blocking <=> self-suspension time
245 t.suspended = res.get_remote_blocking(i)
246 # all blocking, including local blocking
247 t.blocked = res.get_blocking_term(i)
248 t.locally_blocked = res.get_local_blocking(i)
249