aboutsummaryrefslogtreecommitdiffstats
path: root/native/src/blocking/dpcp.cpp
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2012-05-16 11:52:20 -0400
committerBjoern Brandenburg <bbb@mpi-sws.org>2012-05-16 11:52:20 -0400
commitf906d6f40b3f447fd1ba65df3f5e4406972a2331 (patch)
treeb8929ebda202ad77c37584eebbe275ae0461307b /native/src/blocking/dpcp.cpp
parent5fefa18a3dc969640196c1fc9f33b6c1c2a08665 (diff)
C++: Break out the DPCP code into own file
Part of refactoring sharedres.cpp.
Diffstat (limited to 'native/src/blocking/dpcp.cpp')
-rw-r--r--native/src/blocking/dpcp.cpp178
1 files changed, 178 insertions, 0 deletions
diff --git a/native/src/blocking/dpcp.cpp b/native/src/blocking/dpcp.cpp
new file mode 100644
index 0000000..6e194aa
--- /dev/null
+++ b/native/src/blocking/dpcp.cpp
@@ -0,0 +1,178 @@
1#include "sharedres.h"
2#include "blocking.h"
3
4#include "stl-helper.h"
5
6// ************************************************** DPCP **************
7/*
8
9 DPCP blocking terms (Rajkumar, 1991, page 87):
10
11 1) Local PCP blocking => does not apply here, we only care about global
12 resources.
13
14 2) A lower-priority gcs on a remote proc each time that Ji issues a request.
15
16 3) All requests of all higher-priority tasks on all remote processors that Ji
17 accesses.
18
19 4) Global critical sections on Ji's CPU. Since gcs are not part of the job
20 execution time in our model, it does not matter whether the local gcs's
21 belong to lower or higher-priority tasks.
22 */
23
24
25static void split_by_locality(const ResourceSharingInfo& info,
26 const ResourceLocality& locality,
27 AllPerCluster& per_cluster)
28{
29 foreach(info.get_tasks(), it)
30 {
31 while (it->get_cluster() >= per_cluster.size())
32 per_cluster.push_back(ContentionSet());
33
34 foreach(it->get_requests(), jt)
35 {
36 const RequestBound &req = *jt;
37 int cpu = locality[req.get_resource_id()];
38
39 if (cpu == NO_CPU)
40 // NO_CPU => dedicated synchronization processor
41 continue;
42
43 while ((unsigned int) cpu >= per_cluster.size())
44 per_cluster.push_back(ContentionSet());
45
46 per_cluster[cpu].push_back(&req);
47 }
48 }
49}
50
51static unsigned int count_requests_to_cpu(
52 const TaskInfo& tsk,
53 const ResourceLocality& locality,
54 int cpu)
55{
56 unsigned int count = 0;
57
58 foreach(tsk.get_requests(), req)
59 if (locality[req->get_resource_id()] == cpu)
60 count += req->get_num_requests();
61
62 return count;
63}
64
65static Interference bound_blocking_dpcp(
66 const TaskInfo* tsk,
67 const ContentionSet& cont,
68 unsigned int max_lower_prio)
69{
70 Interference inter;
71 const unsigned int interval = tsk->get_response();
72
73 // assumption: cont is ordered by request length
74 foreach(cont, it)
75 {
76 const RequestBound* req = *it;
77
78 // can't block itself
79 if (req->get_task() != tsk)
80 {
81 unsigned int num;
82 if (req->get_task()->get_priority() < tsk->get_priority())
83 {
84 // higher prio => all of them
85 num = req->get_max_num_requests(interval);
86 inter.count += num;
87 inter.total_length += num * req->get_request_length();
88 }
89 else if (max_lower_prio)
90 {
91 // lower prio => only remaining
92 num = std::min(req->get_max_num_requests(interval), max_lower_prio);
93 inter.count += num;
94 inter.total_length += num * req->get_request_length();
95 max_lower_prio -= num;
96 }
97 }
98 }
99
100 return inter;
101}
102
103static Interference dpcp_remote_bound(
104 const TaskInfo& tsk,
105 const ResourceLocality& locality,
106 const AllPerCluster& per_cpu)
107{
108 Interference blocking;
109 unsigned int cpu = 0;
110
111 foreach(per_cpu, it)
112 {
113 // this is about remote delays
114 if (cpu != tsk.get_cluster())
115 {
116 const ContentionSet &cs = *it;
117 unsigned int reqs;
118 reqs = count_requests_to_cpu(tsk, locality, cpu);
119
120 if (reqs > 0)
121 blocking += bound_blocking_dpcp(&tsk, cs, reqs);
122 }
123 cpu++;
124 }
125
126 return blocking;
127}
128
129
130static Interference dpcp_local_bound(
131 const TaskInfo* tsk,
132 const ContentionSet& local)
133{
134 Interference blocking;
135 const unsigned int interval = tsk->get_response();
136
137 foreach(local, it)
138 {
139 const RequestBound* req = *it;
140 if (req->get_task() != tsk)
141 {
142 unsigned int num;
143 num = req->get_max_num_requests(interval);
144 blocking.count += num;
145 blocking.total_length += num * req->get_request_length();
146 }
147 }
148
149 return blocking;
150}
151
152
153BlockingBounds* dpcp_bounds(const ResourceSharingInfo& info,
154 const ResourceLocality& locality)
155{
156 AllPerCluster per_cpu;
157
158 split_by_locality(info, locality, per_cpu);
159 sort_by_request_length(per_cpu);
160
161 BlockingBounds* _results = new BlockingBounds(info);
162 BlockingBounds& results = *_results;
163
164 for (unsigned int i = 0; i < info.get_tasks().size(); i++)
165 {
166 const TaskInfo& tsk = info.get_tasks()[i];
167 Interference remote, local;
168
169 remote = dpcp_remote_bound(tsk, locality, per_cpu);
170 local = dpcp_local_bound(&tsk, per_cpu[tsk.get_cluster()]);
171
172 results[i] = remote + local;
173 results.set_remote_blocking(i, remote);
174 results.set_local_blocking(i, local);
175 }
176 return _results;
177}
178