diff options
| author | Bjoern Brandenburg <bbb@mpi-sws.org> | 2012-05-17 09:41:49 -0400 |
|---|---|---|
| committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2012-05-17 09:41:49 -0400 |
| commit | c2e3e08ef2ce90237b7b50efd0adc1e2848a3729 (patch) | |
| tree | 9574a97377fafda742c6b75a21971a6c909e8394 | |
| parent | 7cd7212e7273c9c137e4bb1825d2b9f3842c882d (diff) | |
C++: Properly consider priority ceilings in DPCP bound
The bound should not reflect requests executed by agents that can be preempted.
| -rw-r--r-- | native/include/blocking.h | 5 | ||||
| -rw-r--r-- | native/src/blocking/dpcp.cpp | 22 | ||||
| -rw-r--r-- | native/src/blocking/mpcp.cpp | 22 | ||||
| -rw-r--r-- | native/src/sharedres.cpp | 20 | ||||
| -rw-r--r-- | tests/locking.py | 36 |
5 files changed, 80 insertions, 25 deletions
diff --git a/native/include/blocking.h b/native/include/blocking.h index b70f1a6..9f8c7d6 100644 --- a/native/include/blocking.h +++ b/native/include/blocking.h | |||
| @@ -82,6 +82,11 @@ Interference bound_blocking_all_clusters( | |||
| 82 | unsigned long interval, | 82 | unsigned long interval, |
| 83 | const TaskInfo* exclude_tsk); | 83 | const TaskInfo* exclude_tsk); |
| 84 | 84 | ||
| 85 | typedef std::vector<unsigned int> PriorityCeilings; | ||
| 86 | |||
| 87 | void determine_priority_ceilings(const Resources& resources, | ||
| 88 | PriorityCeilings& ceilings); | ||
| 89 | |||
| 85 | extern const unsigned int UNLIMITED; | 90 | extern const unsigned int UNLIMITED; |
| 86 | 91 | ||
| 87 | #endif | 92 | #endif |
diff --git a/native/src/blocking/dpcp.cpp b/native/src/blocking/dpcp.cpp index 6e194aa..a9b1288 100644 --- a/native/src/blocking/dpcp.cpp +++ b/native/src/blocking/dpcp.cpp | |||
| @@ -65,6 +65,7 @@ static unsigned int count_requests_to_cpu( | |||
| 65 | static Interference bound_blocking_dpcp( | 65 | static Interference bound_blocking_dpcp( |
| 66 | const TaskInfo* tsk, | 66 | const TaskInfo* tsk, |
| 67 | const ContentionSet& cont, | 67 | const ContentionSet& cont, |
| 68 | const PriorityCeilings& prio_ceiling, | ||
| 68 | unsigned int max_lower_prio) | 69 | unsigned int max_lower_prio) |
| 69 | { | 70 | { |
| 70 | Interference inter; | 71 | Interference inter; |
| @@ -86,7 +87,8 @@ static Interference bound_blocking_dpcp( | |||
| 86 | inter.count += num; | 87 | inter.count += num; |
| 87 | inter.total_length += num * req->get_request_length(); | 88 | inter.total_length += num * req->get_request_length(); |
| 88 | } | 89 | } |
| 89 | else if (max_lower_prio) | 90 | else if (max_lower_prio && |
| 91 | prio_ceiling[req->get_resource_id()] <= tsk->get_priority()) | ||
| 90 | { | 92 | { |
| 91 | // lower prio => only remaining | 93 | // lower prio => only remaining |
| 92 | num = std::min(req->get_max_num_requests(interval), max_lower_prio); | 94 | num = std::min(req->get_max_num_requests(interval), max_lower_prio); |
| @@ -103,6 +105,7 @@ static Interference bound_blocking_dpcp( | |||
| 103 | static Interference dpcp_remote_bound( | 105 | static Interference dpcp_remote_bound( |
| 104 | const TaskInfo& tsk, | 106 | const TaskInfo& tsk, |
| 105 | const ResourceLocality& locality, | 107 | const ResourceLocality& locality, |
| 108 | const PriorityCeilings& prio_ceilings, | ||
| 106 | const AllPerCluster& per_cpu) | 109 | const AllPerCluster& per_cpu) |
| 107 | { | 110 | { |
| 108 | Interference blocking; | 111 | Interference blocking; |
| @@ -118,7 +121,7 @@ static Interference dpcp_remote_bound( | |||
| 118 | reqs = count_requests_to_cpu(tsk, locality, cpu); | 121 | reqs = count_requests_to_cpu(tsk, locality, cpu); |
| 119 | 122 | ||
| 120 | if (reqs > 0) | 123 | if (reqs > 0) |
| 121 | blocking += bound_blocking_dpcp(&tsk, cs, reqs); | 124 | blocking += bound_blocking_dpcp(&tsk, cs, prio_ceilings, reqs); |
| 122 | } | 125 | } |
| 123 | cpu++; | 126 | cpu++; |
| 124 | } | 127 | } |
| @@ -150,6 +153,17 @@ static Interference dpcp_local_bound( | |||
| 150 | } | 153 | } |
| 151 | 154 | ||
| 152 | 155 | ||
| 156 | static PriorityCeilings get_priority_ceilings(const ResourceSharingInfo& info) | ||
| 157 | { | ||
| 158 | Resources resources; | ||
| 159 | PriorityCeilings ceilings; | ||
| 160 | |||
| 161 | split_by_resource(info, resources); | ||
| 162 | determine_priority_ceilings(resources, ceilings); | ||
| 163 | |||
| 164 | return ceilings; | ||
| 165 | } | ||
| 166 | |||
| 153 | BlockingBounds* dpcp_bounds(const ResourceSharingInfo& info, | 167 | BlockingBounds* dpcp_bounds(const ResourceSharingInfo& info, |
| 154 | const ResourceLocality& locality) | 168 | const ResourceLocality& locality) |
| 155 | { | 169 | { |
| @@ -158,6 +172,8 @@ BlockingBounds* dpcp_bounds(const ResourceSharingInfo& info, | |||
| 158 | split_by_locality(info, locality, per_cpu); | 172 | split_by_locality(info, locality, per_cpu); |
| 159 | sort_by_request_length(per_cpu); | 173 | sort_by_request_length(per_cpu); |
| 160 | 174 | ||
| 175 | PriorityCeilings prio_ceilings = get_priority_ceilings(info); | ||
| 176 | |||
| 161 | BlockingBounds* _results = new BlockingBounds(info); | 177 | BlockingBounds* _results = new BlockingBounds(info); |
| 162 | BlockingBounds& results = *_results; | 178 | BlockingBounds& results = *_results; |
| 163 | 179 | ||
| @@ -166,7 +182,7 @@ BlockingBounds* dpcp_bounds(const ResourceSharingInfo& info, | |||
| 166 | const TaskInfo& tsk = info.get_tasks()[i]; | 182 | const TaskInfo& tsk = info.get_tasks()[i]; |
| 167 | Interference remote, local; | 183 | Interference remote, local; |
| 168 | 184 | ||
| 169 | remote = dpcp_remote_bound(tsk, locality, per_cpu); | 185 | remote = dpcp_remote_bound(tsk, locality, prio_ceilings, per_cpu); |
| 170 | local = dpcp_local_bound(&tsk, per_cpu[tsk.get_cluster()]); | 186 | local = dpcp_local_bound(&tsk, per_cpu[tsk.get_cluster()]); |
| 171 | 187 | ||
| 172 | results[i] = remote + local; | 188 | results[i] = remote + local; |
diff --git a/native/src/blocking/mpcp.cpp b/native/src/blocking/mpcp.cpp index 8b87556..655e09e 100644 --- a/native/src/blocking/mpcp.cpp +++ b/native/src/blocking/mpcp.cpp | |||
| @@ -7,28 +7,6 @@ | |||
| 7 | // *************************** MPCP ****************************************** | 7 | // *************************** MPCP ****************************************** |
| 8 | 8 | ||
| 9 | 9 | ||
| 10 | typedef std::vector<unsigned int> PriorityCeilings; | ||
| 11 | |||
| 12 | static void determine_priority_ceilings(const Resources& resources, | ||
| 13 | PriorityCeilings& ceilings) | ||
| 14 | { | ||
| 15 | ceilings.reserve(resources.size()); | ||
| 16 | |||
| 17 | foreach(resources, it) | ||
| 18 | { | ||
| 19 | unsigned int ceiling = UINT_MAX; | ||
| 20 | const ContentionSet& cs = *it; | ||
| 21 | |||
| 22 | foreach(cs, jt) | ||
| 23 | { | ||
| 24 | const RequestBound* req = *jt; | ||
| 25 | ceiling = std::min(ceiling, req->get_task()->get_priority()); | ||
| 26 | } | ||
| 27 | |||
| 28 | ceilings.push_back(ceiling); | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 32 | typedef std::vector<unsigned long> ResponseTimes; | 10 | typedef std::vector<unsigned long> ResponseTimes; |
| 33 | typedef std::vector<ResponseTimes> TaskResponseTimes; | 11 | typedef std::vector<ResponseTimes> TaskResponseTimes; |
| 34 | typedef std::vector<TaskResponseTimes> ClusterResponseTimes; | 12 | typedef std::vector<TaskResponseTimes> ClusterResponseTimes; |
diff --git a/native/src/sharedres.cpp b/native/src/sharedres.cpp index a91bfdf..5c8acee 100644 --- a/native/src/sharedres.cpp +++ b/native/src/sharedres.cpp | |||
| @@ -225,6 +225,26 @@ void sort_by_request_length(ClusterResources& resources) | |||
| 225 | apply_foreach(resources, sort_by_request_length); | 225 | apply_foreach(resources, sort_by_request_length); |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | void determine_priority_ceilings(const Resources& resources, | ||
| 229 | PriorityCeilings& ceilings) | ||
| 230 | { | ||
| 231 | ceilings.reserve(resources.size()); | ||
| 232 | |||
| 233 | foreach(resources, it) | ||
| 234 | { | ||
| 235 | unsigned int ceiling = UINT_MAX; | ||
| 236 | const ContentionSet& cs = *it; | ||
| 237 | |||
| 238 | foreach(cs, jt) | ||
| 239 | { | ||
| 240 | const RequestBound* req = *jt; | ||
| 241 | ceiling = std::min(ceiling, req->get_task()->get_priority()); | ||
| 242 | } | ||
| 243 | |||
| 244 | ceilings.push_back(ceiling); | ||
| 245 | } | ||
| 246 | } | ||
| 247 | |||
| 228 | typedef std::vector<TaskContention> ClusterContention; | 248 | typedef std::vector<TaskContention> ClusterContention; |
| 229 | 249 | ||
| 230 | typedef std::vector<ContentionSet> TaskContention; | 250 | typedef std::vector<ContentionSet> TaskContention; |
diff --git a/tests/locking.py b/tests/locking.py index 73cd8f1..b16c453 100644 --- a/tests/locking.py +++ b/tests/locking.py | |||
| @@ -440,6 +440,42 @@ class Test_dpcp_terms(unittest.TestCase): | |||
| 440 | self.assertEqual(6 + 3, res.get_remote_count(2)) | 440 | self.assertEqual(6 + 3, res.get_remote_count(2)) |
| 441 | self.assertEqual(6 * 3 + 3 * 5, res.get_remote_blocking(2)) | 441 | self.assertEqual(6 * 3 + 3 * 5, res.get_remote_blocking(2)) |
| 442 | 442 | ||
| 443 | def test_priority_ceiling(self): | ||
| 444 | self.rsi = cpp.ResourceSharingInfo(4) | ||
| 445 | |||
| 446 | self.rsi.add_task(10, 10, 2, 100) | ||
| 447 | self.rsi.add_request(0, 1, 3) | ||
| 448 | |||
| 449 | self.rsi.add_task(25, 25, 3, 200) | ||
| 450 | self.rsi.add_request(0, 1, 5) | ||
| 451 | |||
| 452 | self.rsi.add_task(50, 50, 4, 300) | ||
| 453 | self.rsi.add_request(1, 1, 7) | ||
| 454 | |||
| 455 | self.rsi.add_task(100, 100, 1, 400) | ||
| 456 | self.rsi.add_request(1, 1, 9) | ||
| 457 | |||
| 458 | self.loc = cpp.ResourceLocality() | ||
| 459 | self.loc.assign_resource(0, 1) | ||
| 460 | self.loc.assign_resource(1, 1) | ||
| 461 | |||
| 462 | res = cpp.dpcp_bounds(self.rsi, self.loc) | ||
| 463 | |||
| 464 | self.assertEqual(1, res.get_remote_count(0)) | ||
| 465 | self.assertEqual(5, res.get_remote_blocking(0)) | ||
| 466 | |||
| 467 | self.assertEqual(4, res.get_remote_count(1)) | ||
| 468 | self.assertEqual(4 * 3, res.get_remote_blocking(1)) | ||
| 469 | |||
| 470 | self.assertEqual(6 + 3 + 1, res.get_remote_count(2)) | ||
| 471 | self.assertEqual(6 * 3 + 3 * 5 + 1 * 9, res.get_remote_blocking(2)) | ||
| 472 | |||
| 473 | self.assertEqual(0, res.get_remote_count(3)) | ||
| 474 | self.assertEqual(0, res.get_remote_blocking(3)) | ||
| 475 | |||
| 476 | self.assertEqual(11 + 5 + 3, res.get_local_count(3)) | ||
| 477 | self.assertEqual(11 * 3 + 5 * 5 + 3 * 7, res.get_local_blocking(3)) | ||
| 478 | |||
| 443 | 479 | ||
| 444 | class Test_mpcp_terms(unittest.TestCase): | 480 | class Test_mpcp_terms(unittest.TestCase): |
| 445 | 481 | ||
