aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrii Anisov <andrii_anisov@epam.com>2017-08-31 10:14:24 -0400
committerBjörn Brandenburg <bbb@mpi-sws.org>2017-09-08 12:03:42 -0400
commitce8aeb80262d60cdfe762931f6c71e2b5ab22ef7 (patch)
tree6124bbcb9f4c3ab2b0821ed32c26e72172b07cb7
parent35bb1bae9d010ebbb6737d6238b3d5971c0506fc (diff)
Introduce a task configuration based on amount of work
In order to make experiments in virtualized environment it is introduced a task (rtspin) configuration based on amount of work. Though this configuration requires some manual operation for choosing number of cycles burned for 1ms of task execution. First you need to run 'rtspin -A' baremetal or on a virtualized environment with pinned CPUs with 100% bandwidth and take a cycles number for 1ms taks. Optionally verify chosen number with 'rtspin -l -a CYCLES'. Then use the number for workload runs. Signed-off-by: Andrii Anisov <andrii_anisov@epam.com>
-rw-r--r--bin/rtspin.c133
1 files changed, 105 insertions, 28 deletions
diff --git a/bin/rtspin.c b/bin/rtspin.c
index 8a25af2..c69f3e4 100644
--- a/bin/rtspin.c
+++ b/bin/rtspin.c
@@ -19,8 +19,9 @@ const char *usage_msg =
19 "Usage: (1) rtspin OPTIONS WCET PERIOD DURATION\n" 19 "Usage: (1) rtspin OPTIONS WCET PERIOD DURATION\n"
20 " (2) rtspin -S [INPUT] WCET PERIOD DURATION\n" 20 " (2) rtspin -S [INPUT] WCET PERIOD DURATION\n"
21 " (3) rtspin OPTIONS -F FILE [-C COLUMN] WCET PERIOD [DURATION]\n" 21 " (3) rtspin OPTIONS -F FILE [-C COLUMN] WCET PERIOD [DURATION]\n"
22 " (4) rtspin -l\n" 22 " (4) rtspin -l [-a CYCLES]\n"
23 " (5) rtspin -B -m FOOTPRINT\n" 23 " (5) rtspin -B -m FOOTPRINT\n"
24 " (6) rtspin -A\n"
24 "\n" 25 "\n"
25 "Modes: (1) run as periodic task with given WCET and PERIOD\n" 26 "Modes: (1) run as periodic task with given WCET and PERIOD\n"
26 " (2) run as sporadic task with given WCET and PERIOD,\n" 27 " (2) run as sporadic task with given WCET and PERIOD,\n"
@@ -31,12 +32,15 @@ const char *usage_msg =
31 " (4) Run calibration loop (how accurately are target\n" 32 " (4) Run calibration loop (how accurately are target\n"
32 " runtimes met?)\n" 33 " runtimes met?)\n"
33 " (5) Run background, non-real-time cache-thrashing loop.\n" 34 " (5) Run background, non-real-time cache-thrashing loop.\n"
35 " (6) Run 1 ms workload calibration (estimate cycles for 1ms, 10ms, 100ms workload)\n"
34 "\n" 36 "\n"
35 "Required arguments:\n" 37 "Required arguments:\n"
36 " WCET, PERIOD reservation parameters (in ms)\n" 38 " WCET, PERIOD reservation parameters (in ms)\n"
37 " DURATION terminate the task after DURATION seconds\n" 39 " DURATION terminate the task after DURATION seconds\n"
38 "\n" 40 "\n"
39 "Options:\n" 41 "Options:\n"
42 " -A calibrate 1ms workload cycles\n"
43 " -a CYCLES number of cycles for 1ms of workload loop chosen after calibration\n "
40 " -B run non-real-time background loop\n" 44 " -B run non-real-time background loop\n"
41 " -c be|srt|hrt task class (best-effort, soft real-time, hard real-time)\n" 45 " -c be|srt|hrt task class (best-effort, soft real-time, hard real-time)\n"
42 " -d DEADLINE relative deadline, equal to the period by default (in ms)\n" 46 " -d DEADLINE relative deadline, equal to the period by default (in ms)\n"
@@ -165,18 +169,23 @@ static int nr_of_pages = 0;
165static int page_size; 169static int page_size;
166static void *base = NULL; 170static void *base = NULL;
167 171
168static int loop_once(void) 172static int cycles_ms = 0;
173
174static int loop(int count)
169{ 175{
170 int i, j = 0; 176 int i, j = 0;
171 /* touch some numbers and do some math */ 177 /* touch some numbers and do some math */
172 for (i = 0; i < NUMS; i++) { 178 for (i = 0; i < count; i++) {
173 j += num[i]++; 179 int index = i % NUMS;
174 if (j > num[i]) 180 j += num[index]++;
175 num[i] = (j / 2) + 1; 181 if (j > num[index])
182 num[index] = (j / 2) + 1;
176 } 183 }
177 return j; 184 return j;
178} 185}
179 186
187#define loop_once() loop(NUMS)
188
180static int loop_once_with_mem(void) 189static int loop_once_with_mem(void)
181{ 190{
182 int i, j = 0; 191 int i, j = 0;
@@ -202,30 +211,35 @@ static int loop_once_with_mem(void)
202 211
203static int loop_for(double exec_time, double emergency_exit) 212static int loop_for(double exec_time, double emergency_exit)
204{ 213{
205 double last_loop = 0, loop_start;
206 int tmp = 0; 214 int tmp = 0;
207 215
208 double start = cputime(); 216 if (cycles_ms) {
209 double now = cputime(); 217 double count = cycles_ms * exec_time * 1000;
218 tmp += loop(count);
219 } else {
220 double last_loop = 0, loop_start;
221 double start = cputime();
222 double now = cputime();
210 223
211 while (now + last_loop < start + exec_time) { 224 while (now + last_loop < start + exec_time) {
212 loop_start = now; 225 loop_start = now;
213 if (nr_of_pages) 226 if (nr_of_pages)
214 tmp += loop_once_with_mem(); 227 tmp += loop_once_with_mem();
215 else 228 else
216 tmp += loop_once(); 229 tmp += loop_once();
217 now = cputime(); 230 now = cputime();
218 last_loop = now - loop_start; 231 last_loop = now - loop_start;
219 if (emergency_exit && wctime() > emergency_exit) { 232 if (emergency_exit && wctime() > emergency_exit) {
220 /* Oops --- this should only be possible if the 233 /* Oops --- this should only be possible if the
221 * execution time tracking is broken in the LITMUS^RT 234 * execution time tracking is broken in the LITMUS^RT
222 * kernel or the user specified infeasible parameters. 235 * kernel or the user specified infeasible parameters.
223 */ 236 */
224 fprintf(stderr, "!!! rtspin/%d emergency exit!\n", 237 fprintf(stderr, "!!! rtspin/%d emergency exit!\n",
225 getpid()); 238 getpid());
226 fprintf(stderr, "Reached experiment timeout while " 239 fprintf(stderr, "Reached experiment timeout while "
227 "spinning.\n"); 240 "spinning.\n");
228 break; 241 break;
242 }
229 } 243 }
230 } 244 }
231 245
@@ -251,6 +265,51 @@ static void debug_delay_loop(void)
251 } 265 }
252} 266}
253 267
268static int calibrate_ms(int ms)
269{
270 int right = NUMS;
271 int left = 0;
272 int middle;
273
274 double start;
275 double now;
276 double dms = 0.001 * ms;
277
278 /*look for initial loop count values for binary search*/
279 for (;;)
280 {
281 printf("Probe %d loops for %d ms:\n", right, ms);
282 start = wctime();
283 loop(right);
284 now = wctime();
285 if ((now - start) >= dms)
286 break;
287 left = right;
288 right += right;
289 }
290
291 middle = (left + right) / 2;
292
293 /*binary search for a loop count value for expected calibration time*/
294 while (left < middle)
295 {
296 start = wctime();
297 loop(middle);
298 now = wctime();
299
300 printf("%d loops elapsed in %4.20f s\n", middle, now - start);
301
302 if ((now - start) < dms)
303 left = middle;
304 else if ((now - start) == dms)
305 return middle;
306 else
307 right = middle;
308 middle = (left + right) / 2;
309 }
310 return middle;
311}
312
254static int wait_for_input(int event_fd) 313static int wait_for_input(int event_fd)
255{ 314{
256 /* We do a blocking read, accepting up to 4KiB of data. 315 /* We do a blocking read, accepting up to 4KiB of data.
@@ -297,7 +356,7 @@ static void job(double exec_time, double program_end, int lock_od, double cs_len
297 } 356 }
298} 357}
299 358
300#define OPTSTR "p:c:wlveo:F:s:m:q:r:X:L:Q:iRu:U:Bhd:C:S::TD:E:" 359#define OPTSTR "p:c:Awlveo:F:s:m:q:r:X:L:Q:iRu:U:Bhd:C:S::TD:E:a:"
301 360
302int main(int argc, char** argv) 361int main(int argc, char** argv)
303{ 362{
@@ -318,6 +377,7 @@ int main(int argc, char** argv)
318 int opt; 377 int opt;
319 int wait = 0; 378 int wait = 0;
320 int test_loop = 0; 379 int test_loop = 0;
380 int caliber_ms = 0;
321 int background_loop = 0; 381 int background_loop = 0;
322 int column = 1; 382 int column = 1;
323 const char *file = NULL; 383 const char *file = NULL;
@@ -462,6 +522,12 @@ int main(int argc, char** argv)
462 verbose = 1; 522 verbose = 1;
463 report_interrupts = 1; 523 report_interrupts = 1;
464 break; 524 break;
525 case 'A':
526 caliber_ms = 1;
527 break;
528 case 'a':
529 cycles_ms = want_non_negative_int(optarg, "-a");
530 break;
465 case ':': 531 case ':':
466 usage("Argument missing."); 532 usage("Argument missing.");
467 break; 533 break;
@@ -495,10 +561,21 @@ int main(int argc, char** argv)
495 srand(getpid()); 561 srand(getpid());
496 562
497 if (test_loop) { 563 if (test_loop) {
564 if (cycles_ms > 0)
565 printf("Evaluating loop with %d cycles:\n", cycles_ms);
566
498 debug_delay_loop(); 567 debug_delay_loop();
499 return 0; 568 return 0;
500 } 569 }
501 570
571 if (caliber_ms) {
572 printf("In 1 ms %d loops\n", calibrate_ms(1));
573 printf("In 10 ms %d loops\n", calibrate_ms(10));
574 printf("In 100 ms %d loops\n", calibrate_ms(100));
575 printf("In 1 s %d loops\n", calibrate_ms(1000));
576 return 0;
577 }
578
502 if (background_loop) { 579 if (background_loop) {
503 while (1) { 580 while (1) {
504 if (nr_of_pages) 581 if (nr_of_pages)