aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2012-05-16 12:54:10 -0400
committerBjoern Brandenburg <bbb@mpi-sws.org>2012-05-16 12:54:10 -0400
commitb7373fbe338936145b9d55471dc353951cb3a81a (patch)
treed7d58ce6af9526828e96dbd98210f1dba056a631
parent817061bc060265e4682f082eac760c390d378210 (diff)
C++: Break out the C-OMLP-KX code
Part of refactoring sharedres.cpp.
-rw-r--r--native/include/blocking.h18
-rw-r--r--native/src/blocking/clust-omlp.cpp189
-rw-r--r--native/src/sharedres.cpp205
3 files changed, 208 insertions, 204 deletions
diff --git a/native/include/blocking.h b/native/include/blocking.h
index c4b4775..f5a5a13 100644
--- a/native/include/blocking.h
+++ b/native/include/blocking.h
@@ -50,6 +50,24 @@ Interference np_fifo_per_resource(
50void charge_arrival_blocking(const ResourceSharingInfo& info, 50void charge_arrival_blocking(const ResourceSharingInfo& info,
51 BlockingBounds& bounds); 51 BlockingBounds& bounds);
52 52
53
54struct ClusterLimit
55{
56 unsigned int max_total_requests;
57 unsigned int max_requests_per_source;
58
59 ClusterLimit(unsigned int total, unsigned int src) :
60 max_total_requests(total), max_requests_per_source(src) {}
61};
62
63typedef std::vector<ClusterLimit> ClusterLimits;
64
65ClusterLimits np_fifo_limits(
66 const TaskInfo& tsk, const ClusterResources& clusters,
67 unsigned int procs_per_cluster,
68 const unsigned int issued,
69 int dedicated_irq);
70
53extern const unsigned int UNLIMITED; 71extern const unsigned int UNLIMITED;
54 72
55#endif 73#endif
diff --git a/native/src/blocking/clust-omlp.cpp b/native/src/blocking/clust-omlp.cpp
index ed6f110..892608f 100644
--- a/native/src/blocking/clust-omlp.cpp
+++ b/native/src/blocking/clust-omlp.cpp
@@ -2,6 +2,7 @@
2#include "blocking.h" 2#include "blocking.h"
3 3
4#include "stl-helper.h" 4#include "stl-helper.h"
5#include "math-helper.h"
5 6
6BlockingBounds* clustered_omlp_bounds(const ResourceSharingInfo& info, 7BlockingBounds* clustered_omlp_bounds(const ResourceSharingInfo& info,
7 unsigned int procs_per_cluster, 8 unsigned int procs_per_cluster,
@@ -72,3 +73,191 @@ BlockingBounds* clustered_omlp_bounds(const ResourceSharingInfo& info,
72 73
73 return _results; 74 return _results;
74} 75}
76
77static void add_blocking(LimitedContentionSet &lcs,
78 const ContentionSet& cont,
79 unsigned long interval,
80 unsigned int max_total_requests,
81 unsigned int max_requests_per_source,
82 const TaskInfo* exclude_tsk,
83 unsigned int min_priority = 0)
84{
85 unsigned int remaining;
86
87 remaining = max_total_requests;
88
89 foreach(cont, it)
90 {
91 const RequestBound* req = *it;
92
93 if (!remaining)
94 break;
95
96 // only use this source if it is not excluded
97 if (req->get_task() != exclude_tsk &&
98 req->get_task()->get_priority() >= min_priority)
99 {
100 unsigned int num;
101 // This makes the assumption that there is only one
102 // request object per task. See bound_blocking() above.
103 num = std::min(req->get_max_num_requests(interval),
104 max_requests_per_source);
105 num = std::min(num, remaining);
106 remaining -= num;
107 lcs.push_back(LimitedRequestBound(req, num));
108 }
109 }
110}
111
112// Return a contention set that includes the longest requests from all
113// clusters subject to the specified constraints.
114static LimitedContentionSet contention_from_all_clusters(
115 const ClusterResources& clusters,
116 const ClusterLimits& limits,
117 unsigned int res_id,
118 unsigned long interval,
119 const TaskInfo* exclude_tsk)
120{
121 LimitedContentionSet lcs;
122 unsigned int i;
123
124 // add interference from each non-excluded cluster
125 enumerate(clusters, it, i)
126 {
127 const Resources& resources = *it;
128 const ClusterLimit& limit = limits[i];
129
130 if (resources.size() > res_id)
131 add_blocking(lcs, resources[res_id],
132 interval,
133 limit.max_total_requests,
134 limit.max_requests_per_source,
135 exclude_tsk);
136 }
137
138 return lcs;
139}
140
141static LimitedContentionSet np_fifo_per_resource_contention(
142 const TaskInfo& tsk, const ClusterResources& clusters,
143 unsigned int procs_per_cluster,
144 unsigned int res_id, unsigned int issued,
145 int dedicated_irq = NO_CPU)
146{
147 const unsigned long interval = tsk.get_response();
148 ClusterLimits limits = np_fifo_limits(tsk, clusters, procs_per_cluster,
149 issued, dedicated_irq);
150 return contention_from_all_clusters(clusters,
151 limits,
152 res_id,
153 interval,
154 &tsk);
155}
156
157// assumption: lcs is sorted by request length
158static Interference bound_blocking(const LimitedContentionSet &lcs, unsigned int max_total_requests)
159{
160 Interference inter;
161 unsigned int remaining = max_total_requests;
162
163 foreach(lcs, it)
164 {
165 const LimitedRequestBound &lreqb = *it;
166 unsigned int num;
167
168 if (!remaining)
169 break;
170
171 num = std::min(lreqb.limit, remaining);
172
173 inter.total_length += num * lreqb.request_bound->get_request_length();
174 inter.count += num;
175 remaining -= num;
176 }
177
178 return inter;
179}
180
181
182BlockingBounds* clustered_kx_omlp_bounds(const ResourceSharingInfo& info,
183 const ReplicaInfo& replicaInfo,
184 unsigned int procs_per_cluster,
185 int dedicated_irq)
186{
187 // split everything by partition
188 Clusters clusters;
189
190 split_by_cluster(info, clusters);
191
192 const unsigned int num_cpus = clusters.size() * procs_per_cluster -
193 (dedicated_irq != NO_CPU ? 1 : 0);
194
195 // split each partition by resource
196 ClusterResources resources;
197
198 split_by_resource(clusters, resources);
199
200 // sort each contention set by request length
201 sort_by_request_length(resources);
202
203 unsigned int i;
204
205 // direct blocking results
206 BlockingBounds* _results = new BlockingBounds(info);
207 BlockingBounds& results = *_results;
208
209 for (i = 0; i < info.get_tasks().size(); i++)
210 {
211 const TaskInfo& tsk = info.get_tasks()[i];
212
213 Interference bterm;
214
215 foreach(tsk.get_requests(), jt)
216 {
217 const RequestBound& req = *jt;
218
219 unsigned int max_total_once;
220 LimitedContentionSet lcs;
221 Interference blocking;
222
223 max_total_once = divide_with_ceil(num_cpus,
224 replicaInfo[req.get_resource_id()]) - 1;
225
226 lcs = np_fifo_per_resource_contention(
227 tsk, resources, procs_per_cluster,
228 req.get_resource_id(),
229 req.get_num_requests(),
230 dedicated_irq);
231 sort_by_request_length(lcs);
232 blocking = bound_blocking(lcs, max_total_once * req.get_num_requests());
233
234 // add in blocking term
235 bterm += blocking;
236
237 // Keep track of maximum request span.
238 // Is this already a single-issue request?
239 if (req.get_num_requests() != 1)
240 {
241 lcs = np_fifo_per_resource_contention(
242 tsk, resources, procs_per_cluster,
243 req.get_resource_id(),
244 1, dedicated_irq);
245 sort_by_request_length(lcs);
246 blocking = bound_blocking(lcs, max_total_once);
247 }
248
249 // The span includes our own request.
250 blocking.total_length += req.get_request_length();
251 blocking.count += 1;
252 // Update max. request span.
253 results.raise_request_span(i, blocking);
254 }
255
256 results[i] = bterm;
257 }
258
259 // This is the initial delay due to priority donation.
260 charge_arrival_blocking(info, results);
261
262 return _results;
263}
diff --git a/native/src/sharedres.cpp b/native/src/sharedres.cpp
index 976f94e..c988017 100644
--- a/native/src/sharedres.cpp
+++ b/native/src/sharedres.cpp
@@ -284,41 +284,6 @@ Interference bound_blocking(const ContentionSet& cont,
284 return inter; 284 return inter;
285} 285}
286 286
287static void add_blocking(LimitedContentionSet &lcs,
288 const ContentionSet& cont,
289 unsigned long interval,
290 unsigned int max_total_requests,
291 unsigned int max_requests_per_source,
292 const TaskInfo* exclude_tsk,
293 unsigned int min_priority = 0)
294{
295 unsigned int remaining;
296
297 remaining = max_total_requests;
298
299 foreach(cont, it)
300 {
301 const RequestBound* req = *it;
302
303 if (!remaining)
304 break;
305
306 // only use this source if it is not excluded
307 if (req->get_task() != exclude_tsk &&
308 req->get_task()->get_priority() >= min_priority)
309 {
310 unsigned int num;
311 // This makes the assumption that there is only one
312 // request object per task. See bound_blocking() above.
313 num = std::min(req->get_max_num_requests(interval),
314 max_requests_per_source);
315 num = std::min(num, remaining);
316 remaining -= num;
317 lcs.push_back(LimitedRequestBound(req, num));
318 }
319 }
320}
321
322Interference bound_blocking(const ContentionSet& cont, 287Interference bound_blocking(const ContentionSet& cont,
323 unsigned long interval, 288 unsigned long interval,
324 unsigned int max_total_requests, 289 unsigned int max_total_requests,
@@ -357,17 +322,6 @@ Interference bound_blocking(const ContentionSet& cont,
357 return inter; 322 return inter;
358} 323}
359 324
360struct ClusterLimit
361{
362 unsigned int max_total_requests;
363 unsigned int max_requests_per_source;
364
365 ClusterLimit(unsigned int total, unsigned int src) :
366 max_total_requests(total), max_requests_per_source(src) {}
367};
368
369typedef std::vector<ClusterLimit> ClusterLimits;
370
371static Interference bound_blocking_all_clusters( 325static Interference bound_blocking_all_clusters(
372 const ClusterResources& clusters, 326 const ClusterResources& clusters,
373 const ClusterLimits& limits, 327 const ClusterLimits& limits,
@@ -395,36 +349,6 @@ static Interference bound_blocking_all_clusters(
395 return inter; 349 return inter;
396} 350}
397 351
398// Return a contention set that includes the longest requests from all
399// clusters subject to the specified constraints.
400static LimitedContentionSet contention_from_all_clusters(
401 const ClusterResources& clusters,
402 const ClusterLimits& limits,
403 unsigned int res_id,
404 unsigned long interval,
405 const TaskInfo* exclude_tsk)
406{
407 LimitedContentionSet lcs;
408 unsigned int i;
409
410 // add interference from each non-excluded cluster
411 enumerate(clusters, it, i)
412 {
413 const Resources& resources = *it;
414 const ClusterLimit& limit = limits[i];
415
416 if (resources.size() > res_id)
417 add_blocking(lcs, resources[res_id],
418 interval,
419 limit.max_total_requests,
420 limit.max_requests_per_source,
421 exclude_tsk);
422 }
423
424 return lcs;
425}
426
427
428static Interference max_local_request_span(const TaskInfo &tsk, 352static Interference max_local_request_span(const TaskInfo &tsk,
429 const TaskInfos &tasks, 353 const TaskInfos &tasks,
430 const BlockingBounds& bounds) 354 const BlockingBounds& bounds)
@@ -468,7 +392,7 @@ void charge_arrival_blocking(const ResourceSharingInfo& info,
468 392
469// **** blocking term analysis **** 393// **** blocking term analysis ****
470 394
471static ClusterLimits np_fifo_limits( 395ClusterLimits np_fifo_limits(
472 const TaskInfo& tsk, const ClusterResources& clusters, 396 const TaskInfo& tsk, const ClusterResources& clusters,
473 unsigned int procs_per_cluster, 397 unsigned int procs_per_cluster,
474 const unsigned int issued, 398 const unsigned int issued,
@@ -512,133 +436,6 @@ Interference np_fifo_per_resource(
512 &tsk); 436 &tsk);
513} 437}
514 438
515static LimitedContentionSet np_fifo_per_resource_contention(
516 const TaskInfo& tsk, const ClusterResources& clusters,
517 unsigned int procs_per_cluster,
518 unsigned int res_id, unsigned int issued,
519 int dedicated_irq = NO_CPU)
520{
521 const unsigned long interval = tsk.get_response();
522 ClusterLimits limits = np_fifo_limits(tsk, clusters, procs_per_cluster,
523 issued, dedicated_irq);
524 return contention_from_all_clusters(clusters,
525 limits,
526 res_id,
527 interval,
528 &tsk);
529}
530
531
532// assumption: lcs is sorted by request length
533static Interference bound_blocking(const LimitedContentionSet &lcs, unsigned int max_total_requests)
534{
535 Interference inter;
536 unsigned int remaining = max_total_requests;
537
538 foreach(lcs, it)
539 {
540 const LimitedRequestBound &lreqb = *it;
541 unsigned int num;
542
543 if (!remaining)
544 break;
545
546 num = std::min(lreqb.limit, remaining);
547
548 inter.total_length += num * lreqb.request_bound->get_request_length();
549 inter.count += num;
550 remaining -= num;
551 }
552
553 return inter;
554}
555
556
557
558BlockingBounds* clustered_kx_omlp_bounds(const ResourceSharingInfo& info,
559 const ReplicaInfo& replicaInfo,
560 unsigned int procs_per_cluster,
561 int dedicated_irq)
562{
563 // split everything by partition
564 Clusters clusters;
565
566 split_by_cluster(info, clusters);
567
568 const unsigned int num_cpus = clusters.size() * procs_per_cluster -
569 (dedicated_irq != NO_CPU ? 1 : 0);
570
571 // split each partition by resource
572 ClusterResources resources;
573
574 split_by_resource(clusters, resources);
575
576 // sort each contention set by request length
577 sort_by_request_length(resources);
578
579 unsigned int i;
580
581 // direct blocking results
582 BlockingBounds* _results = new BlockingBounds(info);
583 BlockingBounds& results = *_results;
584
585 for (i = 0; i < info.get_tasks().size(); i++)
586 {
587 const TaskInfo& tsk = info.get_tasks()[i];
588
589 Interference bterm;
590
591 foreach(tsk.get_requests(), jt)
592 {
593 const RequestBound& req = *jt;
594
595 unsigned int max_total_once;
596 LimitedContentionSet lcs;
597 Interference blocking;
598
599 max_total_once = divide_with_ceil(num_cpus,
600 replicaInfo[req.get_resource_id()]) - 1;
601
602 lcs = np_fifo_per_resource_contention(
603 tsk, resources, procs_per_cluster,
604 req.get_resource_id(),
605 req.get_num_requests(),
606 dedicated_irq);
607 sort_by_request_length(lcs);
608 blocking = bound_blocking(lcs, max_total_once * req.get_num_requests());
609
610 // add in blocking term
611 bterm += blocking;
612
613 // Keep track of maximum request span.
614 // Is this already a single-issue request?
615 if (req.get_num_requests() != 1)
616 {
617 lcs = np_fifo_per_resource_contention(
618 tsk, resources, procs_per_cluster,
619 req.get_resource_id(),
620 1, dedicated_irq);
621 sort_by_request_length(lcs);
622 blocking = bound_blocking(lcs, max_total_once);
623 }
624
625 // The span includes our own request.
626 blocking.total_length += req.get_request_length();
627 blocking.count += 1;
628 // Update max. request span.
629 results.raise_request_span(i, blocking);
630 }
631
632 results[i] = bterm;
633 }
634
635 // This is the initial delay due to priority donation.
636 charge_arrival_blocking(info, results);
637
638 return _results;
639}
640
641
642struct RWCount { 439struct RWCount {
643 unsigned int res_id; 440 unsigned int res_id;
644 unsigned int num_reads; 441 unsigned int num_reads;