aboutsummaryrefslogtreecommitdiffstats
path: root/native/src/sharedres.cpp
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2012-02-20 12:39:01 -0500
committerBjoern Brandenburg <bbb@mpi-sws.org>2012-02-20 12:39:01 -0500
commitb12d172d6599d7578bc811a36d939d89d415f636 (patch)
tree85a5ee32d0f7e03dde932013dadfae271fdd1604 /native/src/sharedres.cpp
parentb99084aaaf78b4e87ca41b310121b87630239377 (diff)
Add OMLP k-exclusion blocking bounds
Diffstat (limited to 'native/src/sharedres.cpp')
-rw-r--r--native/src/sharedres.cpp251
1 files changed, 235 insertions, 16 deletions
diff --git a/native/src/sharedres.cpp b/native/src/sharedres.cpp
index 7f11ae7..7b61fc3 100644
--- a/native/src/sharedres.cpp
+++ b/native/src/sharedres.cpp
@@ -114,6 +114,20 @@ typedef std::vector<Resources> ClusterResources;
114 114
115typedef std::vector<ContentionSet> AllPerCluster; 115typedef std::vector<ContentionSet> AllPerCluster;
116 116
117
118struct LimitedRequestBound {
119 LimitedRequestBound(const RequestBound *rqb, unsigned int l) :
120 request_bound(rqb), limit(l) {};
121 LimitedRequestBound() : request_bound(NULL), limit(0) {};
122
123 const RequestBound *request_bound;
124 unsigned int limit;
125};
126
127typedef std::vector<LimitedRequestBound> LimitedContentionSet;
128
129
130
117static void split_by_resource(const ResourceSharingInfo& info, Resources& resources) 131static void split_by_resource(const ResourceSharingInfo& info, Resources& resources)
118{ 132{
119 foreach(info.get_tasks(), it) 133 foreach(info.get_tasks(), it)
@@ -242,6 +256,17 @@ static void sort_by_request_length(ContentionSet& cs)
242 std::sort(cs.begin(), cs.end(), has_longer_request_length); 256 std::sort(cs.begin(), cs.end(), has_longer_request_length);
243} 257}
244 258
259static bool has_longer_request_length_lcs(const LimitedRequestBound &a,
260 const LimitedRequestBound &b)
261{
262 return has_longer_request_length(a.request_bound, b.request_bound);
263}
264
265static void sort_by_request_length(LimitedContentionSet &lcs)
266{
267 std::sort(lcs.begin(), lcs.end(), has_longer_request_length_lcs);
268}
269
245static void sort_by_request_length(Resources& resources) 270static void sort_by_request_length(Resources& resources)
246{ 271{
247 apply_foreach(resources, sort_by_request_length); 272 apply_foreach(resources, sort_by_request_length);
@@ -329,6 +354,41 @@ static Interference bound_blocking(const ContentionSet& cont,
329 return inter; 354 return inter;
330} 355}
331 356
357static void add_blocking(LimitedContentionSet &lcs,
358 const ContentionSet& cont,
359 unsigned long interval,
360 unsigned int max_total_requests,
361 unsigned int max_requests_per_source,
362 const TaskInfo* exclude_tsk,
363 unsigned int min_priority = 0)
364{
365 unsigned int remaining;
366
367 remaining = max_total_requests;
368
369 foreach(cont, it)
370 {
371 const RequestBound* req = *it;
372
373 if (!remaining)
374 break;
375
376 // only use this source if it is not excluded
377 if (req->get_task() != exclude_tsk &&
378 req->get_task()->get_priority() >= min_priority)
379 {
380 unsigned int num;
381 // This makes the assumption that there is only one
382 // request object per task. See bound_blocking() above.
383 num = std::min(req->get_max_num_requests(interval),
384 max_requests_per_source);
385 num = std::min(num, remaining);
386 remaining -= num;
387 lcs.push_back(LimitedRequestBound(req, num));
388 }
389 }
390}
391
332static Interference bound_blocking(const ContentionSet& cont, 392static Interference bound_blocking(const ContentionSet& cont,
333 unsigned long interval, 393 unsigned long interval,
334 unsigned int max_total_requests, 394 unsigned int max_total_requests,
@@ -405,6 +465,35 @@ static Interference bound_blocking_all_clusters(
405 return inter; 465 return inter;
406} 466}
407 467
468// Return a contention set that includes the longest requests from all
469// clusters subject to the specified constraints.
470static LimitedContentionSet contention_from_all_clusters(
471 const ClusterResources& clusters,
472 const ClusterLimits& limits,
473 unsigned int res_id,
474 unsigned long interval,
475 const TaskInfo* exclude_tsk)
476{
477 LimitedContentionSet lcs;
478 unsigned int i;
479
480 // add interference from each non-excluded cluster
481 enumerate(clusters, it, i)
482 {
483 const Resources& resources = *it;
484 const ClusterLimit& limit = limits[i];
485
486 if (resources.size() > res_id)
487 add_blocking(lcs, resources[res_id],
488 interval,
489 limit.max_total_requests,
490 limit.max_requests_per_source,
491 exclude_tsk);
492 }
493
494 return lcs;
495}
496
408 497
409static Interference max_local_request_span(const TaskInfo &tsk, 498static Interference max_local_request_span(const TaskInfo &tsk,
410 const TaskInfos &tasks, 499 const TaskInfos &tasks,
@@ -553,17 +642,12 @@ BlockingBounds* global_fmlp_bounds(const ResourceSharingInfo& info)
553 return _results; 642 return _results;
554} 643}
555 644
556static Interference np_fifo_per_resource( 645static ClusterLimits np_fifo_limits(
557 const TaskInfo& tsk, const ClusterResources& clusters, 646 const TaskInfo& tsk, const ClusterResources& clusters,
558 unsigned int procs_per_cluster, 647 unsigned int procs_per_cluster,
559 unsigned int res_id, unsigned int issued, 648 const unsigned int issued,
560 int dedicated_irq = NO_CPU) 649 int dedicated_irq)
561{ 650{
562 const unsigned long interval = tsk.get_response();
563 // At most one blocking request per remote task per
564 // request.
565 const unsigned int per_src_limit = issued;
566
567 ClusterLimits limits; 651 ClusterLimits limits;
568 int idx; 652 int idx;
569 limits.reserve(clusters.size()); 653 limits.reserve(clusters.size());
@@ -580,16 +664,67 @@ static Interference np_fifo_per_resource(
580 // At most one blocking request per remote CPU in 664 // At most one blocking request per remote CPU in
581 // cluster per request. 665 // cluster per request.
582 total = issued * parallelism; 666 total = issued * parallelism;
583 limits.push_back(ClusterLimit(total, per_src_limit)); 667 limits.push_back(ClusterLimit(total, issued));
584 } 668 }
585 669
586 Interference blocking; 670 return limits;
587 blocking = bound_blocking_all_clusters(clusters, 671}
588 limits, 672
589 res_id, 673static Interference np_fifo_per_resource(
590 interval, 674 const TaskInfo& tsk, const ClusterResources& clusters,
591 &tsk); 675 unsigned int procs_per_cluster,
592 return blocking; 676 unsigned int res_id, unsigned int issued,
677 int dedicated_irq = NO_CPU)
678{
679 const unsigned long interval = tsk.get_response();
680 ClusterLimits limits = np_fifo_limits(tsk, clusters, procs_per_cluster,
681 issued, dedicated_irq);
682 return bound_blocking_all_clusters(clusters,
683 limits,
684 res_id,
685 interval,
686 &tsk);
687}
688
689static LimitedContentionSet np_fifo_per_resource_contention(
690 const TaskInfo& tsk, const ClusterResources& clusters,
691 unsigned int procs_per_cluster,
692 unsigned int res_id, unsigned int issued,
693 int dedicated_irq = NO_CPU)
694{
695 const unsigned long interval = tsk.get_response();
696 ClusterLimits limits = np_fifo_limits(tsk, clusters, procs_per_cluster,
697 issued, dedicated_irq);
698 return contention_from_all_clusters(clusters,
699 limits,
700 res_id,
701 interval,
702 &tsk);
703}
704
705
706// assumption: lcs is sorted by request length
707static Interference bound_blocking(const LimitedContentionSet &lcs, unsigned int max_total_requests)
708{
709 Interference inter;
710 unsigned int remaining = max_total_requests;
711
712 foreach(lcs, it)
713 {
714 const LimitedRequestBound &lreqb = *it;
715 unsigned int num;
716
717 if (!remaining)
718 break;
719
720 num = std::min(lreqb.limit, remaining);
721
722 inter.total_length += num * lreqb.request_bound->get_request_length();
723 inter.count += num;
724 remaining -= num;
725 }
726
727 return inter;
593} 728}
594 729
595BlockingBounds* part_omlp_bounds(const ResourceSharingInfo& info) 730BlockingBounds* part_omlp_bounds(const ResourceSharingInfo& info)
@@ -730,6 +865,90 @@ BlockingBounds* clustered_omlp_bounds(const ResourceSharingInfo& info,
730 return _results; 865 return _results;
731} 866}
732 867
868BlockingBounds* clustered_kx_omlp_bounds(const ResourceSharingInfo& info,
869 const ReplicaInfo& replicaInfo,
870 unsigned int procs_per_cluster,
871 int dedicated_irq)
872{
873 // split everything by partition
874 Clusters clusters;
875
876 split_by_cluster(info, clusters);
877
878 const unsigned int num_cpus = clusters.size() * procs_per_cluster -
879 (dedicated_irq != NO_CPU ? 1 : 0);
880
881 // split each partition by resource
882 ClusterResources resources;
883
884 split_by_resource(clusters, resources);
885
886 // sort each contention set by request length
887 sort_by_request_length(resources);
888
889 unsigned int i;
890
891 // direct blocking results
892 BlockingBounds* _results = new BlockingBounds(info);
893 BlockingBounds& results = *_results;
894
895 for (i = 0; i < info.get_tasks().size(); i++)
896 {
897 const TaskInfo& tsk = info.get_tasks()[i];
898
899 Interference bterm;
900
901 foreach(tsk.get_requests(), jt)
902 {
903 const RequestBound& req = *jt;
904
905 unsigned int max_total_once;
906 LimitedContentionSet lcs;
907 Interference blocking;
908
909 max_total_once = divide_with_ceil(num_cpus,
910 replicaInfo[req.get_resource_id()]) - 1;
911
912 lcs = np_fifo_per_resource_contention(
913 tsk, resources, procs_per_cluster,
914 req.get_resource_id(),
915 req.get_num_requests(),
916 dedicated_irq);
917 sort_by_request_length(lcs);
918 blocking = bound_blocking(lcs, max_total_once * req.get_num_requests());
919
920 // add in blocking term
921 bterm += blocking;
922
923 // Keep track of maximum request span.
924 // Is this already a single-issue request?
925 if (req.get_num_requests() != 1)
926 {
927 lcs = np_fifo_per_resource_contention(
928 tsk, resources, procs_per_cluster,
929 req.get_resource_id(),
930 1, dedicated_irq);
931 sort_by_request_length(lcs);
932 blocking = bound_blocking(lcs, max_total_once);
933 }
934
935 // The span includes our own request.
936 blocking.total_length += req.get_request_length();
937 blocking.count += 1;
938 // Update max. request span.
939 results.raise_request_span(i, blocking);
940 }
941
942 results[i] = bterm;
943 }
944
945 // This is the initial delay due to priority donation.
946 charge_arrival_blocking(info, results);
947
948 return _results;
949}
950
951
733struct RWCount { 952struct RWCount {
734 unsigned int res_id; 953 unsigned int res_id;
735 unsigned int num_reads; 954 unsigned int num_reads;