aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2013-01-29 07:47:01 -0500
committerBjoern Brandenburg <bbb@mpi-sws.org>2013-07-12 08:19:22 -0400
commit064f6a2915d8bcecea31f07b2a57de80203c6f37 (patch)
tree92ce02d07ba1779e434942616113f967c42d79ed
parente17645921697351bd968f034a85299c02332ad16 (diff)
Implement LP-based OMIP blocking analysis
-rw-r--r--native/Makefile2
-rw-r--r--native/include/lp_analysis.h5
-rw-r--r--native/include/lp_common.h9
-rw-r--r--native/include/sharedres_types.h7
-rw-r--r--native/src/blocking/linprog/lp_common.cpp34
-rw-r--r--native/src/blocking/linprog/lp_omip.cpp268
-rw-r--r--schedcat/locking/bounds.py6
-rw-r--r--tests/locking.py4
8 files changed, 334 insertions, 1 deletions
diff --git a/native/Makefile b/native/Makefile
index 6f1abe2..54c75d8 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 lp_fmlp.o 121LP_OBJ = lp_common.o io.o lp_dflp.o lp_dpcp.o lp_mpcp.o lp_fmlp.o lp_omip.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 998eeb5..862c09e 100644
--- a/native/include/lp_analysis.h
+++ b/native/include/lp_analysis.h
@@ -13,4 +13,9 @@ BlockingBounds* lp_mpcp_bounds(const ResourceSharingInfo& info);
13 13
14BlockingBounds* lp_part_fmlp_bounds(const ResourceSharingInfo& info); 14BlockingBounds* lp_part_fmlp_bounds(const ResourceSharingInfo& info);
15 15
16BlockingBounds* lp_omip_bounds(
17 const ResourceSharingInfo& info,
18 unsigned int num_procs,
19 unsigned int cluster_size);
20
16#endif /* LP_ANALYSYS_H_ */ 21#endif /* LP_ANALYSYS_H_ */
diff --git a/native/include/lp_common.h b/native/include/lp_common.h
index b459664..8f612ea 100644
--- a/native/include/lp_common.h
+++ b/native/include/lp_common.h
@@ -19,6 +19,9 @@ enum blocking_type
19 BLOCKING_PREEMPT 19 BLOCKING_PREEMPT
20}; 20};
21 21
22// s-oblivious analysis reuses BLOCKING_DIRECT as a catch-all blocking type.
23#define BLOCKING_SOB BLOCKING_DIRECT
24
22class VarMapper { 25class VarMapper {
23private: 26private:
24 hashmap<uint64_t, unsigned int> map; 27 hashmap<uint64_t, unsigned int> map;
@@ -97,6 +100,12 @@ void set_blocking_objective_part_shm(
97 LinearExpression *local_obj = 0, 100 LinearExpression *local_obj = 0,
98 LinearExpression *remote_obj = 0); 101 LinearExpression *remote_obj = 0);
99 102
103void set_blocking_objective_sob(
104 VarMapper& vars,
105 const ResourceSharingInfo& info,
106 const TaskInfo& ti,
107 LinearProgram& lp);
108
100void add_mutex_constraints(VarMapper& vars, 109void add_mutex_constraints(VarMapper& vars,
101 const ResourceSharingInfo& info, 110 const ResourceSharingInfo& info,
102 const TaskInfo& ti, LinearProgram& lp); 111 const TaskInfo& ti, LinearProgram& lp);
diff --git a/native/include/sharedres_types.h b/native/include/sharedres_types.h
index 898434c..fbe8f72 100644
--- a/native/include/sharedres_types.h
+++ b/native/include/sharedres_types.h
@@ -119,6 +119,13 @@ public:
119 return len; 119 return len;
120 } 120 }
121 121
122 unsigned int get_num_requests(unsigned int res_id) const
123 {
124 foreach(requests, it)
125 if (it->get_resource_id() == res_id)
126 return it->get_num_requests();
127 return 0;
128 }
122}; 129};
123 130
124typedef std::vector<TaskInfo> TaskInfos; 131typedef std::vector<TaskInfo> TaskInfos;
diff --git a/native/src/blocking/linprog/lp_common.cpp b/native/src/blocking/linprog/lp_common.cpp
index 1715d3b..2df1284 100644
--- a/native/src/blocking/linprog/lp_common.cpp
+++ b/native/src/blocking/linprog/lp_common.cpp
@@ -119,6 +119,40 @@ void set_blocking_objective_part_shm(
119 } 119 }
120} 120}
121 121
122// This version is for suspension-oblivious shared-memory protocols,
123// where the analysis does not differentiate among the different kinds
124// of blocking (since they are all just added to the execution time anyway).
125void set_blocking_objective_sob(
126 VarMapper& vars,
127 const ResourceSharingInfo& info,
128 const TaskInfo& ti,
129 LinearProgram& lp)
130{
131 LinearExpression *obj;
132
133 obj = lp.get_objective();
134
135 foreach_task_except(info.get_tasks(), ti, tx)
136 {
137 unsigned int t = tx->get_id();
138
139 foreach(tx->get_requests(), request)
140 {
141 unsigned int q = request->get_resource_id();
142 double length = request->get_request_length();;
143
144 foreach_request_instance(*request, ti, v)
145 {
146 unsigned int var_id;
147
148 var_id = vars.lookup(t, q, v, BLOCKING_SOB);
149 obj->add_term(length, var_id);
150 }
151 }
152 }
153}
154
155
122// Constraint 1 in [Brandenburg 2013] 156// Constraint 1 in [Brandenburg 2013]
123void add_mutex_constraints( 157void add_mutex_constraints(
124 VarMapper& vars, 158 VarMapper& vars,
diff --git a/native/src/blocking/linprog/lp_omip.cpp b/native/src/blocking/linprog/lp_omip.cpp
new file mode 100644
index 0000000..0e5d864
--- /dev/null
+++ b/native/src/blocking/linprog/lp_omip.cpp
@@ -0,0 +1,268 @@
1#include <iostream>
2#include <set>
3#include <algorithm>
4#include <cmath>
5
6#include "lp_common.h"
7#include "blocking.h"
8#include "stl-hashmap.h"
9
10#include "cpu_time.h"
11
12// Per-cluster, per-resource access counts.
13typedef hashmap<unsigned int, unsigned int> AccessCounts;
14typedef hashmap<unsigned int, AccessCounts> PerClusterACounts;
15
16static AccessCounts count_accesses(
17 const ResourceSharingInfo& info,
18 unsigned int cluster)
19{
20 AccessCounts acount;
21
22 foreach(info.get_tasks(), tx) {
23 if (tx->get_cluster() == cluster) {
24 foreach(tx->get_requests(), request)
25 {
26 unsigned int q = request->get_resource_id();
27 // count that q is being accessed by tx
28 acount[q] += 1;
29 }
30 }
31 }
32 return acount;
33}
34
35static void add_total_constraints(
36 VarMapper& vars,
37 const ResourceSharingInfo& info,
38 const TaskInfo& ti,
39 LinearProgram& lp,
40 unsigned int num_procs)
41{
42 // one constraint for each resource
43 hashmap<unsigned int, LinearExpression *> constraints;
44 LinearExpression *exp;
45
46 foreach_task_except(info.get_tasks(), ti, tx)
47 {
48 unsigned int t = tx->get_id();
49
50 //for all requests accessed by tx
51 foreach(tx->get_requests(), request)
52 {
53 unsigned int q = request->get_resource_id();
54
55 if (constraints.find(q) == constraints.end())
56 constraints[q] = new LinearExpression();
57 exp = constraints[q];
58 foreach_request_instance(*request, ti, v)
59 {
60 unsigned int var_id;
61 var_id = vars.lookup(t, q, v, BLOCKING_SOB);
62 exp->add_var(var_id);
63 }
64 }
65 }
66
67 // add each per-resource constraint
68 foreach(constraints, it) {
69 unsigned int bound = ti.get_num_requests(it->first);
70 bound *= (2 * num_procs - 1);
71 lp.add_inequality(it->second, bound);
72 }
73}
74
75
76static void add_remote_cluster_constraints(
77 VarMapper& vars,
78 const ResourceSharingInfo& info,
79 const TaskInfo& ti,
80 LinearProgram& lp,
81 AccessCounts& acount,
82 unsigned int num_procs,
83 unsigned int cl