aboutsummaryrefslogtreecommitdiffstats
path: root/native/src/blocking
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 /native/src/blocking
parente17645921697351bd968f034a85299c02332ad16 (diff)
Implement LP-based OMIP blocking analysis
Diffstat (limited to 'native/src/blocking')
-rw-r--r--native/src/blocking/linprog/lp_common.cpp34
-rw-r--r--native/src/blocking/linprog/lp_omip.cpp268
2 files changed, 302 insertions, 0 deletions
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 cluster_size)
84{
85 // one constraint for each cluster and each resource
86 hashmap<unsigned int, hashmap<unsigned int, LinearExpression *> > cluster_c;
87 LinearExpression *exp;
88
89 foreach_remote_task(info.get_tasks(), ti, tx)
90 {
91 unsigned int t = tx->get_id();
92 unsigned int c = tx->get_cluster();
93
94 hashmap<unsigned int, LinearExpression *> &constraints = cluster_c[c];
95
96 //for all requests accessed by tx
97 foreach(tx->get_requests(), request)
98 {
99 unsigned int q = request->get_resource_id();
100
101 if (constraints.find(q) == constraints.end())
102 constraints[q] = new LinearExpression();
103 exp = constraints[q];
104
105 foreach_request_instance(*request, ti, v)
106 {
107 unsigned int var_id;
108 var_id = vars.lookup(t, q, v, BLOCKING_SOB);
109 exp->add_var(var_id);
110 }
111 }
112 }
113
114 // add each per-resource constraint
115 foreach(cluster_c, ct) {
116 assert(ct->first != ti.get_cluster());
117 foreach(ct->second, it) {
118 unsigned int bound = ti.get_num_requests(it->first);
119 unsigned int q = it->first;
120 if (acount[q] <= 2 * cluster_size) {
121 // FQ-only case
122 bound *= acount[q];
123 } else {
124 // PQ case
125 bound *= (cluster_size + num_procs);
126 }
127 lp.add_inequality(it->second, bound);
128 }
129 }
130}
131
132static void add_local_cluster_constraints(
133 VarMapper& vars,
134 const ResourceSharingInfo& info,
135 const TaskInfo& ti,
136 LinearProgram& lp,
137 AccessCounts& acount,
138 unsigned int cluster_size)
139{
140 foreach_local_task_except(info.get_tasks(), ti, tx)
141 {
142 unsigned int t = tx->get_id();
143 //for all requests accessed by tx
144 foreach(tx->get_requests(), request)
145 {
146 unsigned int q = request->get_resource_id();
147 LinearExpression *exp = new LinearExpression();
148
149 foreach_request_instance(*request, ti, v)
150 {
151 unsigned int var_id;
152 var_id = vars.lookup(t, q, v, BLOCKING_SOB);
153 exp->add_var(var_id);
154 }
155 unsigned int bound = ti.get_num_requests(q);
156 if (acount[q] > 2 * cluster_size)
157 bound *= 2; // PQ case
158 lp.add_inequality(exp, bound);
159 }