diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-05-26 17:29:58 -0400 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-05-26 17:29:58 -0400 |
commit | a463f9a9e04385f0729f7435a0a6dff7d89b25de (patch) | |
tree | 00ff42c305926c800e18b13df8440a4de1a1a041 /litmus/gpu_affinity.c | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
GPUSync patch for Litmus 2012.1.
Diffstat (limited to 'litmus/gpu_affinity.c')
-rw-r--r-- | litmus/gpu_affinity.c | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/litmus/gpu_affinity.c b/litmus/gpu_affinity.c new file mode 100644 index 000000000000..9762be1a085e --- /dev/null +++ b/litmus/gpu_affinity.c | |||
@@ -0,0 +1,113 @@ | |||
1 | |||
2 | #ifdef CONFIG_LITMUS_NVIDIA | ||
3 | |||
4 | #include <linux/sched.h> | ||
5 | #include <litmus/litmus.h> | ||
6 | #include <litmus/gpu_affinity.h> | ||
7 | |||
8 | #include <litmus/sched_trace.h> | ||
9 | |||
10 | #define OBSERVATION_CAP 2*1e9 | ||
11 | |||
12 | static fp_t update_estimate(feedback_est_t* fb, fp_t a, fp_t b, lt_t observed) | ||
13 | { | ||
14 | fp_t relative_err; | ||
15 | fp_t err, new; | ||
16 | fp_t actual = _integer_to_fp(observed); | ||
17 | |||
18 | err = _sub(actual, fb->est); | ||
19 | new = _add(_mul(a, err), _mul(b, fb->accum_err)); | ||
20 | |||
21 | relative_err = _div(err, actual); | ||
22 | |||
23 | fb->est = new; | ||
24 | fb->accum_err = _add(fb->accum_err, err); | ||
25 | |||
26 | return relative_err; | ||
27 | } | ||
28 | |||
29 | void update_gpu_estimate(struct task_struct *t, lt_t observed) | ||
30 | { | ||
31 | feedback_est_t *fb = &(tsk_rt(t)->gpu_migration_est[tsk_rt(t)->gpu_migration]); | ||
32 | |||
33 | BUG_ON(tsk_rt(t)->gpu_migration > MIG_LAST); | ||
34 | |||
35 | if(unlikely(fb->est.val == 0)) { | ||
36 | // kludge-- cap observed values to prevent whacky estimations. | ||
37 | // whacky stuff happens during the first few jobs. | ||
38 | if(unlikely(observed > OBSERVATION_CAP)) { | ||
39 | TRACE_TASK(t, "Crazy observation was capped: %llu -> %llu\n", | ||
40 | observed, OBSERVATION_CAP); | ||
41 | observed = OBSERVATION_CAP; | ||
42 | } | ||
43 | |||
44 | // take the first observation as our estimate | ||
45 | // (initial value of 0 was bogus anyhow) | ||
46 | fb->est = _integer_to_fp(observed); | ||
47 | fb->accum_err = _div(fb->est, _integer_to_fp(2)); // ...seems to work. | ||
48 | } | ||
49 | else { | ||
50 | fp_t rel_err = update_estimate(fb, | ||
51 | tsk_rt(t)->gpu_fb_param_a[tsk_rt(t)->gpu_migration], | ||
52 | tsk_rt(t)->gpu_fb_param_b[tsk_rt(t)->gpu_migration], | ||
53 | observed); | ||
54 | |||
55 | if(unlikely(_fp_to_integer(fb->est) <= 0)) { | ||
56 | TRACE_TASK(t, "Invalid estimate. Patching.\n"); | ||
57 | fb->est = _integer_to_fp(observed); | ||
58 | fb->accum_err = _div(fb->est, _integer_to_fp(2)); // ...seems to work. | ||
59 | } | ||
60 | else { | ||
61 | // struct migration_info mig_info; | ||
62 | |||
63 | sched_trace_prediction_err(t, | ||
64 | &(tsk_rt(t)->gpu_migration), | ||
65 | &rel_err); | ||
66 | |||
67 | // mig_info.observed = observed; | ||
68 | // mig_info.estimated = get_gpu_estimate(t, tsk_rt(t)->gpu_migration); | ||
69 | // mig_info.distance = tsk_rt(t)->gpu_migration; | ||
70 | // | ||
71 | // sched_trace_migration(t, &mig_info); | ||
72 | } | ||
73 | } | ||
74 | |||
75 | TRACE_TASK(t, "GPU est update after (dist = %d, obs = %llu): %d.%d\n", | ||
76 | tsk_rt(t)->gpu_migration, | ||
77 | observed, | ||
78 | _fp_to_integer(fb->est), | ||
79 | _point(fb->est)); | ||
80 | } | ||
81 | |||
82 | gpu_migration_dist_t gpu_migration_distance(int a, int b) | ||
83 | { | ||
84 | // GPUs organized in a binary hierarchy, no more than 2^MIG_FAR GPUs | ||
85 | int i; | ||
86 | int dist; | ||
87 | |||
88 | if(likely(a >= 0 && b >= 0)) { | ||
89 | for(i = 0; i <= MIG_FAR; ++i) { | ||
90 | if(a>>i == b>>i) { | ||
91 | dist = i; | ||
92 | goto out; | ||
93 | } | ||
94 | } | ||
95 | dist = MIG_NONE; // hopefully never reached. | ||
96 | TRACE_CUR("WARNING: GPU distance too far! %d -> %d\n", a, b); | ||
97 | } | ||
98 | else { | ||
99 | dist = MIG_NONE; | ||
100 | } | ||
101 | |||
102 | out: | ||
103 | TRACE_CUR("Distance %d -> %d is %d\n", | ||
104 | a, b, dist); | ||
105 | |||
106 | return dist; | ||
107 | } | ||
108 | |||
109 | |||
110 | |||
111 | |||
112 | #endif | ||
113 | |||