aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/gpu_affinity.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-04-18 16:24:56 -0400
committerGlenn Elliott <gelliott@cs.unc.edu>2012-04-18 16:24:56 -0400
commit6ab36ca992441f7353840c70fc91d99a500a940e (patch)
treef7b89f379a04a681a80eee32f86a2405b162616f /litmus/gpu_affinity.c
parent440aa2083245b81583980e3f4177f3b4cc805556 (diff)
Fixed and tested aff-aware KFMLP. (finally!)
Diffstat (limited to 'litmus/gpu_affinity.c')
-rw-r--r--litmus/gpu_affinity.c87
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
8static void update_estimate(feedback_est_t* fb, fp_t* a, fp_t* b, lt_t observed) 8#define OBSERVATION_CAP 2*1e9
9
10static 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
41gpu_migration_dist_t gpu_migration_distance(int a, int b) 64gpu_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; 84out:
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