aboutsummaryrefslogtreecommitdiffstats
path: root/native/src/blocking/linprog/lp_fmlp.cpp
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 /native/src/blocking/linprog/lp_fmlp.cpp
parentadfef1cb9a8960690fb85cc0b99e8fe266e173eb (diff)
Add LP-based blocking analysis for FMLP+
Diffstat (limited to 'native/src/blocking/linprog/lp_fmlp.cpp')
-rw-r--r--native/src/blocking/linprog/lp_fmlp.cpp286
1 files changed, 286 insertions, 0 deletions
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}