diff options
| author | Bjoern Brandenburg <bbb@mpi-sws.org> | 2012-02-20 12:39:01 -0500 |
|---|---|---|
| committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2012-02-20 12:39:01 -0500 |
| commit | b12d172d6599d7578bc811a36d939d89d415f636 (patch) | |
| tree | 85a5ee32d0f7e03dde932013dadfae271fdd1604 /native/src/sharedres.cpp | |
| parent | b99084aaaf78b4e87ca41b310121b87630239377 (diff) | |
Add OMLP k-exclusion blocking bounds
Diffstat (limited to 'native/src/sharedres.cpp')
| -rw-r--r-- | native/src/sharedres.cpp | 251 |
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 | ||
| 115 | typedef std::vector<ContentionSet> AllPerCluster; | 115 | typedef std::vector<ContentionSet> AllPerCluster; |
| 116 | 116 | ||
| 117 | |||
| 118 | struct 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 | |||
| 127 | typedef std::vector<LimitedRequestBound> LimitedContentionSet; | ||
| 128 | |||
| 129 | |||
| 130 | |||
| 117 | static void split_by_resource(const ResourceSharingInfo& info, Resources& resources) | 131 | static 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 | ||
| 259 | static 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 | |||
| 265 | static void sort_by_request_length(LimitedContentionSet &lcs) | ||
| 266 | { | ||
| 267 | std::sort(lcs.begin(), lcs.end(), has_longer_request_length_lcs); | ||
| 268 | } | ||
| 269 | |||
| 245 | static void sort_by_request_length(Resources& resources) | 270 | static 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 | ||
| 357 | static 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 | |||
| 332 | static Interference bound_blocking(const ContentionSet& cont, | 392 | static 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. | ||
| 470 | static 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 | ||
| 409 | static Interference max_local_request_span(const TaskInfo &tsk, | 498 | static 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 | ||
| 556 | static Interference np_fifo_per_resource( | 645 | static 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, | 673 | static 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 | |||
| 689 | static 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 | ||
| 707 | static 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 | ||
| 595 | BlockingBounds* part_omlp_bounds(const ResourceSharingInfo& info) | 730 | BlockingBounds* 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 | ||
| 868 | BlockingBounds* 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 | |||
| 733 | struct RWCount { | 952 | struct RWCount { |
| 734 | unsigned int res_id; | 953 | unsigned int res_id; |
| 735 | unsigned int num_reads; | 954 | unsigned int num_reads; |
