diff options
author | Bjoern Brandenburg <bbb@mpi-sws.org> | 2012-05-16 12:54:10 -0400 |
---|---|---|
committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2012-05-16 12:54:10 -0400 |
commit | b7373fbe338936145b9d55471dc353951cb3a81a (patch) | |
tree | d7d58ce6af9526828e96dbd98210f1dba056a631 | |
parent | 817061bc060265e4682f082eac760c390d378210 (diff) |
C++: Break out the C-OMLP-KX code
Part of refactoring sharedres.cpp.
-rw-r--r-- | native/include/blocking.h | 18 | ||||
-rw-r--r-- | native/src/blocking/clust-omlp.cpp | 189 | ||||
-rw-r--r-- | native/src/sharedres.cpp | 205 |
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( | |||
50 | void charge_arrival_blocking(const ResourceSharingInfo& info, | 50 | void charge_arrival_blocking(const ResourceSharingInfo& info, |
51 | BlockingBounds& bounds); | 51 | BlockingBounds& bounds); |
52 | 52 | ||
53 | |||
54 | struct 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 | |||
63 | typedef std::vector<ClusterLimit> ClusterLimits; | ||
64 | |||
65 | ClusterLimits 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 | |||
53 | extern const unsigned int UNLIMITED; | 71 | extern 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 | ||
6 | BlockingBounds* clustered_omlp_bounds(const ResourceSharingInfo& info, | 7 | BlockingBounds* 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 | |||
77 | static 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. | ||
114 | static 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 | |||
141 | static 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 | ||
158 | static 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 | |||
182 | BlockingBounds* 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 | ||
287 | static 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 | |||
322 | Interference bound_blocking(const ContentionSet& cont, | 287 | Interference 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 | ||
360 | struct 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 | |||
369 | typedef std::vector<ClusterLimit> ClusterLimits; | ||
370 | |||
371 | static Interference bound_blocking_all_clusters( | 325 | static 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. | ||
400 | static 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 | |||
428 | static Interference max_local_request_span(const TaskInfo &tsk, | 352 | static 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 | ||
471 | static ClusterLimits np_fifo_limits( | 395 | ClusterLimits 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 | ||
515 | static 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 | ||
533 | static 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 | |||
558 | BlockingBounds* 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 | |||
642 | struct RWCount { | 439 | struct RWCount { |
643 | unsigned int res_id; | 440 | unsigned int res_id; |
644 | unsigned int num_reads; | 441 | unsigned int num_reads; |