diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-04-18 16:24:56 -0400 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-04-18 16:24:56 -0400 |
commit | 6ab36ca992441f7353840c70fc91d99a500a940e (patch) | |
tree | f7b89f379a04a681a80eee32f86a2405b162616f /litmus/gpu_affinity.c | |
parent | 440aa2083245b81583980e3f4177f3b4cc805556 (diff) |
Fixed and tested aff-aware KFMLP. (finally!)
Diffstat (limited to 'litmus/gpu_affinity.c')
-rw-r--r-- | litmus/gpu_affinity.c | 87 |
1 files changed, 55 insertions, 32 deletions
diff --git a/litmus/gpu_affinity.c b/litmus/gpu_affinity.c index 43171390bed7..87349fe10a9b 100644 --- a/litmus/gpu_affinity.c +++ b/litmus/gpu_affinity.c | |||
@@ -5,15 +5,16 @@ | |||
5 | #include <litmus/litmus.h> | 5 | #include <litmus/litmus.h> |
6 | #include <litmus/gpu_affinity.h> | 6 | #include <litmus/gpu_affinity.h> |
7 | 7 | ||
8 | static void update_estimate(feedback_est_t* fb, fp_t* a, fp_t* b, lt_t observed) | 8 | #define OBSERVATION_CAP 2*1e9 |
9 | |||
10 | static void update_estimate(feedback_est_t* fb, fp_t a, fp_t b, lt_t observed) | ||
9 | { | 11 | { |
10 | fp_t err, new; | 12 | fp_t err, new; |
11 | fp_t actual = _frac(observed, 1); // observed is in ns, so beware of overflow! | 13 | fp_t actual = _integer_to_fp(observed); |
12 | 14 | ||
13 | err = _sub(actual, fb->est); | 15 | err = _sub(actual, fb->est); |
14 | new = _add(_mul(*a, err), | 16 | new = _add(_mul(a, err), _mul(b, fb->accum_err)); |
15 | _mul(*b, fb->accum_err)); | 17 | |
16 | |||
17 | fb->est = new; | 18 | fb->est = new; |
18 | fb->accum_err = _add(fb->accum_err, err); | 19 | fb->accum_err = _add(fb->accum_err, err); |
19 | } | 20 | } |
@@ -22,47 +23,69 @@ void update_gpu_estimate(struct task_struct *t, lt_t observed) | |||
22 | { | 23 | { |
23 | feedback_est_t *fb = &(tsk_rt(t)->gpu_migration_est[tsk_rt(t)->gpu_migration]); | 24 | feedback_est_t *fb = &(tsk_rt(t)->gpu_migration_est[tsk_rt(t)->gpu_migration]); |
24 | 25 | ||
25 | TRACE_TASK(t, "GPU est update before (dist = %d): %d.%d\n", | 26 | WARN_ON(tsk_rt(t)->gpu_migration > MIG_LAST); |
26 | tsk_rt(t)->gpu_migration, | ||
27 | _fp_to_integer(fb->est), | ||
28 | _point(fb->est)); | ||
29 | |||
30 | update_estimate(fb, | ||
31 | &tsk_rt(t)->gpu_fb_param_a, | ||
32 | &tsk_rt(t)->gpu_fb_param_b, | ||
33 | observed); | ||
34 | 27 | ||
35 | TRACE_TASK(t, "GPU est update after (dist = %d): %d.%d\n", | 28 | if(unlikely(fb->est.val == 0)) { |
29 | // kludge-- cap observed values to prevent whacky estimations. | ||
30 | // whacky stuff happens during the first few jobs. | ||
31 | if(unlikely(observed > OBSERVATION_CAP)) { | ||
32 | TRACE_TASK(t, "Crazy observation was capped: %llu -> %llu\n", | ||
33 | observed, OBSERVATION_CAP); | ||
34 | observed = OBSERVATION_CAP; | ||
35 | } | ||
36 | |||
37 | // take the first observation as our estimate | ||
38 | // (initial value of 0 was bogus anyhow) | ||
39 | fb->est = _integer_to_fp(observed); | ||
40 | fb->accum_err = _div(fb->est, _integer_to_fp(2)); // ...seems to work. | ||
41 | } | ||
42 | else { | ||
43 | update_estimate(fb, | ||
44 | tsk_rt(t)->gpu_fb_param_a, | ||
45 | tsk_rt(t)->gpu_fb_param_b, | ||
46 | observed); | ||
47 | |||
48 | if(_fp_to_integer(fb->est) <= 0) { | ||
49 | // TODO: talk to Jonathan about how well this works. | ||
50 | // Maybe we should average the observed and est instead? | ||
51 | TRACE_TASK(t, "Invalid estimate. Patching.\n"); | ||
52 | fb->est = _integer_to_fp(observed); | ||
53 | fb->accum_err = _div(fb->est, _integer_to_fp(2)); // ...seems to work. | ||
54 | } | ||
55 | } | ||
56 | |||
57 | TRACE_TASK(t, "GPU est update after (dist = %d, obs = %llu): %d.%d\n", | ||
36 | tsk_rt(t)->gpu_migration, | 58 | tsk_rt(t)->gpu_migration, |
59 | observed, | ||
37 | _fp_to_integer(fb->est), | 60 | _fp_to_integer(fb->est), |
38 | _point(fb->est)); | 61 | _point(fb->est)); |
39 | } | 62 | } |
40 | 63 | ||
41 | gpu_migration_dist_t gpu_migration_distance(int a, int b) | 64 | gpu_migration_dist_t gpu_migration_distance(int a, int b) |
42 | { | 65 | { |
43 | // GPUs organized in a binary hierarchy, no more than 2^MIG_LAST GPUs | 66 | // GPUs organized in a binary hierarchy, no more than 2^MIG_FAR GPUs |
44 | int i; | 67 | int i; |
45 | int level; | 68 | int dist; |
46 | int max_level; | ||
47 | 69 | ||
48 | if(unlikely(a < 0 || b < 0)) { | 70 | if(likely(a >= 0 && b >= 0)) { |
49 | return MIG_LAST; | 71 | for(i = 0; i <= MIG_FAR; ++i) { |
72 | if(a>>i == b>>i) { | ||
73 | dist = i; | ||
74 | goto out; | ||
75 | } | ||
76 | } | ||
77 | dist = MIG_NONE; // hopefully never reached. | ||
78 | TRACE_CUR("WARNING: GPU distance too far! %d -> %d\n", a, b); | ||
50 | } | 79 | } |
51 | 80 | else { | |
52 | if(a == b) { | 81 | dist = MIG_NONE; |
53 | return MIG_LOCAL; | ||
54 | } | 82 | } |
55 | 83 | ||
56 | for(i = 1, level = 2, max_level = 1<<MIG_LAST; | 84 | out: |
57 | level <= max_level; | 85 | TRACE_CUR("Distance %d -> %d is %d\n", |
58 | ++i, level <<= 1) { | 86 | a, b, dist); |
59 | if(a/level == b/level) { | ||
60 | return (gpu_migration_dist_t)(i); | ||
61 | } | ||
62 | } | ||
63 | 87 | ||
64 | WARN_ON(1); | 88 | return dist; |
65 | return MIG_LAST; | ||
66 | } | 89 | } |
67 | 90 | ||
68 | 91 | ||