aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2012-10-02 06:12:43 -0400
committerBjoern Brandenburg <bbb@mpi-sws.org>2013-02-12 06:55:16 -0500
commitadfef1cb9a8960690fb85cc0b99e8fe266e173eb (patch)
tree71bcc895f00a20c9c631963b223cf4c297bdce6f
parent5b01c84940965f053f5eacd401a132a2008dac71 (diff)
Add LP-based blocking analysis for MPCP
-rw-r--r--native/Makefile4
-rw-r--r--native/include/lp_analysis.h2
-rw-r--r--native/include/lp_common.h22
-rw-r--r--native/src/blocking/linprog/lp_common.cpp108
-rw-r--r--native/src/blocking/linprog/lp_mpcp.cpp589
-rw-r--r--schedcat/locking/bounds.py11
6 files changed, 734 insertions, 2 deletions
diff --git a/native/Makefile b/native/Makefile
index d722fcd..2df9893 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 121LP_OBJ = lp_common.o io.o lp_dflp.o lp_dpcp.o lp_mpcp.o
122 122
123ifneq ($(CPLEX_PATH),) 123ifneq ($(CPLEX_PATH),)
124LP_OBJ += cplex.o cpx.o 124LP_OBJ += cplex.o cpx.o
@@ -159,5 +159,5 @@ _locking.so: ${SYNC_OBJ} interface/locking_wrap.o
159_sim.so: ${CORE_OBJ} ${SCHED_OBJ} interface/sim_wrap.o 159_sim.so: ${CORE_OBJ} ${SCHED_OBJ} interface/sim_wrap.o
160 $(CXX) $(SOFLAGS) $(PYTHON_LIB) -o $@ $+ $(LDFLAGS) 160 $(CXX) $(SOFLAGS) $(PYTHON_LIB) -o $@ $+ $(LDFLAGS)
161 161
162_lp_analysis.so: ${LP_OBJ} sharedres.o cpu_time.o interface/lp_analysis_wrap.o 162_lp_analysis.so: ${LP_OBJ} sharedres.o mpcp.o cpu_time.o interface/lp_analysis_wrap.o
163 $(CXX) $(SOFLAGS) $(PYTHON_LIB) -o $@ $+ $(LDFLAGS) 163 $(CXX) $(SOFLAGS) $(PYTHON_LIB) -o $@ $+ $(LDFLAGS)
diff --git a/native/include/lp_analysis.h b/native/include/lp_analysis.h
index c33be61..182eff1 100644
--- a/native/include/lp_analysis.h
+++ b/native/include/lp_analysis.h
@@ -9,4 +9,6 @@ extern BlockingBounds* lp_dpcp_bounds(const ResourceSharingInfo& info,
9extern BlockingBounds* lp_dflp_bounds(const ResourceSharingInfo& info, 9extern BlockingBounds* lp_dflp_bounds(const ResourceSharingInfo& info,
10 const ResourceLocality& locality); 10 const ResourceLocality& locality);
11 11
12extern BlockingBounds* lp_mpcp_bounds(const ResourceSharingInfo& info);
13
12#endif /* LP_ANALYSYS_H_ */ 14#endif /* LP_ANALYSYS_H_ */
diff --git a/native/include/lp_common.h b/native/include/lp_common.h
index 06c5e78..b459664 100644
--- a/native/include/lp_common.h
+++ b/native/include/lp_common.h
@@ -118,6 +118,18 @@ void add_topology_constraints_shm(
118 const TaskInfo& ti, 118 const TaskInfo& ti,
119 LinearProgram& lp); 119 LinearProgram& lp);
120 120
121void add_local_lower_priority_constraints_shm(
122 VarMapper& vars,
123 const ResourceSharingInfo& info,
124 const TaskInfo& ti,
125 LinearProgram& lp);
126
127void add_local_higher_priority_constraints_shm(
128 VarMapper& vars,
129 const ResourceSharingInfo& info,
130 const TaskInfo& ti,
131 LinearProgram& lp);
132
121// A generic for loop that iterates 'request_index_variable' from 0 to the 133// A generic for loop that iterates 'request_index_variable' from 0 to the
122// maximum number of requests issued by task tx while ti is pending. 'tx_request' 134// maximum number of requests issued by task tx while ti is pending. 'tx_request'
123// should be of type RequestBound&. 135// should be of type RequestBound&.
@@ -169,6 +181,16 @@ void add_topology_constraints_shm(
169 foreach(tasks, task_iter) \ 181 foreach(tasks, task_iter) \
170 if (task_iter->get_cluster() != (local_task).get_cluster()) 182 if (task_iter->get_cluster() != (local_task).get_cluster())
171 183
184// iterate only over tasks with equal or lower priority, excluding local tasks
185#define foreach_remote_lowereq_priority_task(tasks, reference_task, task_iter) \
186 foreach_remote_task(tasks, reference_task, task_iter) \
187 if (task_iter->get_priority() >= (reference_task).get_priority())
188
189// iterate only over tasks with higher priority, excluding local tasks
190#define foreach_remote_higher_priority_task(tasks, reference_task, task_iter) \
191 foreach_remote_task(tasks, reference_task, task_iter) \
192 if (task_iter->get_priority() < (reference_task).get_priority())
193
172#define foreach_local_task(tasks, local_task, task_iter) \ 194#define foreach_local_task(tasks, local_task, task_iter) \
173 foreach(tasks, task_iter) \ 195 foreach(tasks, task_iter) \
174 if (task_iter->get_cluster() == (local_task).get_cluster()) 196 if (task_iter->get_cluster() == (local_task).get_cluster())
diff --git a/native/src/blocking/linprog/lp_common.cpp b/native/src/blocking/linprog/lp_common.cpp
index a7bb1b5..1715d3b 100644
--- a/native/src/blocking/linprog/lp_common.cpp
+++ b/native/src/blocking/linprog/lp_common.cpp
@@ -234,6 +234,7 @@ void add_local_lower_priority_constraints(
234} 234}
235 235
236 236
237// Constraint 10 in [Brandenburg 2013]
237// For shared-memory protocols. 238// For shared-memory protocols.
238// Remote tasks cannot preempt Ti since they are not scheduled 239// Remote tasks cannot preempt Ti since they are not scheduled
239// on Ti's assigned task; therefore force BLOCKING_PREEMPT to zero. 240// on Ti's assigned task; therefore force BLOCKING_PREEMPT to zero.
@@ -261,3 +262,110 @@ void add_topology_constraints_shm(
261 } 262 }
262 lp.add_equality(exp, 0); 263 lp.add_equality(exp, 0);
263} 264}
265
266// Constraint 9 in [Brandenburg 2013]
267// local higher-priority tasks never cause blocking under SHM protocols
268void add_local_higher_priority_constraints_shm(
269 VarMapper& vars,
270 const ResourceSharingInfo& info,
271 const TaskInfo& ti,
272 LinearProgram& lp)
273{
274 LinearExpression *exp = new LinearExpression();
275
276 foreach_local_task(info.get_tasks(), ti, tx)
277 {
278 if (tx->get_priority() < ti.get_priority())
279 {
280 unsigned int t = tx->get_id();
281 foreach(tx->get_requests(), request)
282 {
283 unsigned int q = request->get_resource_id();
284 foreach_request_instance(*request, ti, v)
285 {
286 unsigned int var_id;
287 var_id = vars.lookup(t, q, v,
288 BLOCKING_PREEMPT);
289 exp->add_var(var_id);
290
291 var_id = vars.lookup(t, q, v,
292 BLOCKING_INDIRECT);
293 exp->add_var(var_id);
294
295 var_id = vars.lookup(t, q, v,
296 BLOCKING_DIRECT);
297 exp->add_var(var_id);
298 }
299 }
300 }
301 }
302 lp.add_equality(exp, 0);
303}
304
305static unsigned int max_num_arrivals_shm(
306 const ResourceSharingInfo& info,
307 const TaskInfo& ti)
308{
309 hashmap<unsigned int, unsigned int> request_counts;
310
311 foreach(ti.get_requests(), req)
312 request_counts[req->get_resource_id()] = 0;
313
314 // count how often each resource is accessed on remote cores
315 foreach_remote_task(info.get_tasks(), ti, tx)
316 {
317 foreach(tx->get_requests(), req)
318 {
319 unsigned int q = req->get_resource_id();
320 if (request_counts.find(q) != request_counts.end())
321 request_counts[q] += req->get_max_num_requests(ti.get_response());
322 }
323 }
324
325 // initialize to 1 to account for job release
326 unsigned int total = 1;
327
328 foreach(ti.get_requests(), req)
329 total += std::min(request_counts[req->get_resource_id()],
330 req->get_num_requests());
331
332 return total;
333}
334
335// Constraint 11 in [Brandenburg 2013]
336// Local lower-priority tasks block at most once each time
337// that Ti suspends (and once after release).
338void add_local_lower_priority_constraints_shm(
339 VarMapper& vars,
340 const ResourceSharingInfo& info,
341 const TaskInfo& ti,
342 LinearProgram& lp)
343{
344 unsigned int num_arrivals = max_num_arrivals_shm(info, ti);
345
346 foreach_local_lowereq_priority_task_except(info.get_tasks(), ti, tx)
347 {
348 LinearExpression *exp = new LinearExpression();
349 unsigned int t = tx->get_id();
350 foreach(tx->get_requests(), request)
351 {
352 unsigned int q = request->get_resource_id();
353 foreach_request_instance(*request, ti, v)
354 {
355 unsigned int var_id;
356 var_id = vars.lookup(t, q, v,
357 BLOCKING_PREEMPT);
358 exp->add_var(var_id);
359
360 var_id = vars.lookup(t, q, v,
361 BLOCKING_INDIRECT);
362 exp->add_var(var_id);
363
364 var_id = vars.lookup(t, q, v,
365 BLOCKING_DIRECT);
366 exp->add_var(var_id);
367 }
368 }
369 lp.add_equality(exp, num_arrivals);
370 }
371}
diff --git a/native/src/blocking/linprog/lp_mpcp.cpp b/native/src/blocking/linprog/lp_mpcp.cpp
new file mode 100644
index 0000000..bccea5d
--- /dev/null
+++ b/