diff options
author | Christopher Kenna <cjk@cs.unc.edu> | 2012-04-11 00:53:24 -0400 |
---|---|---|
committer | Christopher Kenna <cjk@cs.unc.edu> | 2012-04-11 00:53:24 -0400 |
commit | b0355b8cc0609be264042c5570e8c13078888636 (patch) | |
tree | 462ddf6a3de3016f97dfac19b62879eb52ac62f0 | |
parent | 041df061efacf3a8e83edb47ac4db37e67e1a258 (diff) |
updates to benchmarking program
-rw-r--r-- | bin/colorbench.c | 220 | ||||
-rw-r--r-- | bin/colortest.c | 4 | ||||
-rw-r--r-- | bin/rtspin.c | 2 |
3 files changed, 163 insertions, 63 deletions
diff --git a/bin/colorbench.c b/bin/colorbench.c index 186bf92..8547bef 100644 --- a/bin/colorbench.c +++ b/bin/colorbench.c | |||
@@ -1,71 +1,131 @@ | |||
1 | #include <stdint.h> /* for uint32_t */ | 1 | #include <stdint.h> /* for uint16_t */ |
2 | #include <stdlib.h> | 2 | #include <stdlib.h> |
3 | #include <limits.h> | ||
3 | #include <pthread.h> | 4 | #include <pthread.h> |
4 | #include <sched.h> | 5 | #include <sched.h> |
5 | #include <sys/mman.h> | 6 | #include <sys/mman.h> |
6 | 7 | #include <errno.h> | |
7 | #define DEBUG 1 | ||
8 | #ifdef DEBUG | ||
9 | #include <stdio.h> | 8 | #include <stdio.h> |
10 | #endif | ||
11 | 9 | ||
12 | #include <litmus/rt_param.h> | 10 | #include <litmus/rt_param.h> |
13 | 11 | ||
14 | #include "color.h" | 12 | #include "color.h" |
15 | 13 | ||
16 | #define NR_CPUS 4 | 14 | #define DEBUG 1 |
15 | #define NR_LOOPS 1000 | ||
16 | |||
17 | /* Ludwig */ | ||
18 | //#define NR_CPUS 6 | ||
19 | //#define CACHE_SIZE_MB 12 | ||
20 | //#define ASSOC 12 | ||
21 | |||
22 | /* Pound */ | ||
23 | //#define NR_CPUS 4 | ||
24 | //#define CACHE_SIZE_MB 8 | ||
25 | //#define ASSOC 16 | ||
26 | |||
27 | /* VM */ | ||
28 | #define NR_CPUS 4 | ||
29 | #define CACHE_SIZE_MB 4 | ||
30 | #define ASSOC 16 | ||
31 | |||
32 | #define LINE_SIZE 64 | ||
33 | #define CACHE_SIZE (CACHE_SIZE_MB * 1024 * 1024) | ||
34 | #define TOTAL_COLORS (CACHE_SIZE / ASSOC / PAGE_SIZE) | ||
35 | |||
36 | #define ARENA_PAGES (arena_size / PAGE_SIZE) | ||
37 | #define USE_COLORS (TOTAL_COLORS >> color_shift) | ||
38 | #define CONTIG_COLORS (ARENA_PAGES / USE_COLORS) | ||
39 | |||
40 | #define PAGE_LOWER ((PAGE_SIZE - 1)) | ||
41 | #define ARENA_INTS (arena_size / sizeof(int)) | ||
17 | 42 | ||
43 | #define THREAD_CPU(t) (t * (NR_CPUS / nr_threads)) | ||
44 | |||
45 | #define FNAME_LEN 512 | ||
18 | struct pthread_state { | 46 | struct pthread_state { |
19 | int thread; | 47 | pthread_t thread; |
48 | int tid; | ||
20 | int retval; | 49 | int retval; |
21 | struct color_ctrl_page *color_ctrl; | 50 | struct color_ctrl_page *color_ctrl; |
22 | int *arena; | 51 | int *arena; |
52 | char fname[FNAME_LEN]; | ||
23 | }; | 53 | }; |
24 | 54 | ||
25 | static pthread_mutex_t ready_mutex; | 55 | static pthread_barrier_t barrier; |
26 | static pthread_cond_t ready_cond; | 56 | static int nr_threads; |
27 | static int nr_ready; | 57 | static int arena_size; |
28 | static int arena_size = 5 * PAGE_SIZE; | 58 | static int color_shift; |
59 | |||
60 | #ifdef DEBUG | ||
61 | #define debug_print(fmt, args...) do { \ | ||
62 | fprintf(stderr, fmt, ##args); \ | ||
63 | } while (0) | ||
64 | #define debug_print_thread(ts, fmt, args...) do { \ | ||
65 | debug_print("T%d: " fmt, ts->tid, ##args); \ | ||
66 | } while (0) | ||
67 | #else | ||
68 | #define debug_print(fmt, args...) do {} while (0) | ||
69 | #define debug_print_thread(ts, fmt, args...) do {} while (0) | ||
70 | #endif | ||
29 | 71 | ||
30 | #define ARENA_INTS (arena_size / sizeof(int)) | 72 | static void mk_fname(struct pthread_state *state) |
73 | { | ||
74 | snprintf(state->fname, FNAME_LEN, "cache_size=%d_line=%d_assoc=%d_" | ||
75 | "colors=%d_color-shift=%d_use-colors=%d_arena-size=%d_" | ||
76 | "arena-pages=%d_contig-colors=%d_thread=%d_" | ||
77 | "cpu=%d", | ||
78 | CACHE_SIZE, LINE_SIZE, ASSOC, TOTAL_COLORS, | ||
79 | color_shift, USE_COLORS, arena_size, | ||
80 | ARENA_PAGES, CONTIG_COLORS, state->tid, | ||
81 | THREAD_CPU(state->tid)); | ||
82 | } | ||
83 | |||
84 | static void setup_colors(struct pthread_state *state) | ||
85 | { | ||
86 | int i, j; | ||
87 | for (i = 0; i < USE_COLORS; i++) { | ||
88 | for (j = 0; j < CONTIG_COLORS; j++) | ||
89 | state->color_ctrl->colors[CONTIG_COLORS * i + j] = i; | ||
90 | } | ||
91 | } | ||
31 | 92 | ||
32 | static int loop_once(struct pthread_state *state) | 93 | static int loop_once(struct pthread_state *state) |
33 | { | 94 | { |
34 | int i, j = 0; | 95 | int i, j = 0; |
35 | for (i = 0; i < ARENA_INTS; i++) | 96 | for (i = 0; i < ARENA_INTS; i += 1) |
36 | j += state->arena[i]++; | 97 | j = state->arena[i]; |
37 | return j; | 98 | return j; |
38 | } | 99 | } |
39 | 100 | ||
40 | int thread_init(struct pthread_state *state) | 101 | int thread_init(struct pthread_state *state) |
41 | { | 102 | { |
103 | const int cpu = THREAD_CPU(state->tid); | ||
42 | cpu_set_t cpu_set; | 104 | cpu_set_t cpu_set; |
43 | int err = 0; | 105 | int err = 0; |
44 | 106 | ||
107 | mk_fname(state); | ||
108 | debug_print_thread(state, "%s\n", state->fname); | ||
109 | |||
45 | CPU_ZERO(&cpu_set); | 110 | CPU_ZERO(&cpu_set); |
46 | CPU_SET(state->thread, &cpu_set); | 111 | CPU_SET(cpu, &cpu_set); |
47 | err = sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set); | 112 | err = sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set); |
48 | if (err) { | 113 | if (err) { |
49 | #ifdef DEBUG | 114 | debug_print_thread(state, "set affinity failed\n"); |
50 | fprintf(stderr, "T%d: set affinity failed\n", state->thread); | ||
51 | #endif | ||
52 | goto out; | 115 | goto out; |
53 | } | 116 | } |
54 | 117 | ||
55 | err = map_color_ctrl((void**)&state->color_ctrl); | 118 | err = map_color_ctrl((void**)&state->color_ctrl); |
56 | if (err) { | 119 | if (err) { |
57 | #ifdef DEBUG | 120 | debug_print_thread(state, "mapping control device failed\n"); |
58 | fprintf(stderr, "couldn't map control device\n"); | ||
59 | #endif | ||
60 | goto out; | 121 | goto out; |
61 | } | 122 | } |
62 | 123 | ||
63 | state->color_ctrl->colors[0] = state->thread; | 124 | setup_colors(state); |
125 | |||
64 | state->arena = color_malloc(arena_size); | 126 | state->arena = color_malloc(arena_size); |
65 | if (!state->arena) { | 127 | if (!state->arena) { |
66 | #ifdef DEBUG | 128 | debug_print_thread(state, "alloc arena failed\n"); |
67 | fprintf(stderr, "T%d: alloc arena failed\n", state->thread); | ||
68 | #endif | ||
69 | err = 1; | 129 | err = 1; |
70 | goto out; | 130 | goto out; |
71 | } | 131 | } |
@@ -73,20 +133,22 @@ int thread_init(struct pthread_state *state) | |||
73 | err = mlockall(MCL_CURRENT|MCL_FUTURE); | 133 | err = mlockall(MCL_CURRENT|MCL_FUTURE); |
74 | if (err) | 134 | if (err) |
75 | { | 135 | { |
76 | #ifdef DEBUG | 136 | debug_print_thread(state, "mlockall failed\n"); |
77 | fprintf(stderr, "T%d: mlockall failed\n", state->thread); | ||
78 | #endif | ||
79 | goto out; | 137 | goto out; |
80 | } | 138 | } |
81 | out: | 139 | out: |
82 | return err; | 140 | return err; |
83 | } | 141 | } |
84 | 142 | ||
143 | #ifdef DEBUG | ||
85 | #define CHECKPRINT(func, ...) do { \ | 144 | #define CHECKPRINT(func, ...) do { \ |
86 | int err = func(__VA_ARGS__); \ | 145 | int err = func(__VA_ARGS__); \ |
87 | if (err) \ | 146 | if (err) \ |
88 | fprintf(stderr, "T%d: func failed\n", state->thread); \ | 147 | fprintf(stderr, "T%d: func failed\n", state->tid); \ |
89 | } while (0) | 148 | } while (0) |
149 | #else | ||
150 | #define CHECKPRINT(func, ...) func(__VA_ARGS__) | ||
151 | #endif | ||
90 | 152 | ||
91 | void * thread_start(void *data) | 153 | void * thread_start(void *data) |
92 | { | 154 | { |
@@ -97,72 +159,110 @@ void * thread_start(void *data) | |||
97 | if (state->retval) | 159 | if (state->retval) |
98 | goto out; | 160 | goto out; |
99 | 161 | ||
100 | CHECKPRINT(pthread_mutex_lock, &ready_mutex); | ||
101 | nr_ready++; | ||
102 | if (NR_CPUS == nr_ready) { | ||
103 | CHECKPRINT(pthread_cond_broadcast, &ready_cond); | ||
104 | } else { | ||
105 | while (NR_CPUS > nr_ready) | ||
106 | CHECKPRINT(pthread_cond_wait, &ready_cond, &ready_mutex); | ||
107 | } | ||
108 | CHECKPRINT(pthread_mutex_unlock, &ready_mutex); | ||
109 | |||
110 | loop_once(state); | 162 | loop_once(state); |
111 | 163 | ||
112 | for (i = 0; i < 1e5; ++i) | 164 | for (i = 0; i < NR_LOOPS; ++i) { |
165 | pthread_barrier_wait(&barrier); | ||
113 | loop_once(state); | 166 | loop_once(state); |
167 | } | ||
114 | out: | 168 | out: |
115 | pthread_exit(&state->retval); | 169 | pthread_exit(&state->retval); |
116 | } | 170 | } |
117 | 171 | ||
118 | static struct pthread_state pthread_state[NR_CPUS]; | 172 | int xstrtol(char *str, long int *conv) |
173 | { | ||
174 | char *endptr; | ||
175 | long int val; | ||
176 | int err = 0; | ||
177 | |||
178 | errno = 0; | ||
179 | val = strtol(str, &endptr, 0); | ||
180 | if (0 == val && str == endptr) { | ||
181 | err = 1; | ||
182 | goto out; | ||
183 | } | ||
184 | if (ERANGE == errno && (LONG_MIN == val || LONG_MAX == val)) { | ||
185 | err = 1; | ||
186 | goto out; | ||
187 | } | ||
188 | *conv = val; | ||
189 | out: | ||
190 | return err; | ||
191 | } | ||
192 | |||
193 | static struct pthread_state *pthread_state; | ||
119 | 194 | ||
120 | #define CHECK(fun, ...) { \ | 195 | #define CHECK(fun, ...) { \ |
121 | int err = fun(__VA_ARGS__); \ | 196 | int err = fun(__VA_ARGS__); \ |
122 | if (err) \ | 197 | if (err) { \ |
198 | debug_print(#fun " failed\n"); \ | ||
123 | return err; \ | 199 | return err; \ |
200 | } \ | ||
124 | } | 201 | } |
125 | 202 | ||
126 | int main(int argc, char **argv) | 203 | int main(int argc, char **argv) |
127 | { | 204 | { |
128 | int ret = 0, err, i; | 205 | int ret = 0, err, i; |
129 | 206 | long int strtol_val; | |
130 | pthread_t threads[NR_CPUS]; | ||
131 | pthread_attr_t attr; | 207 | pthread_attr_t attr; |
132 | 208 | ||
209 | if (argc < 3) { | ||
210 | debug_print("usage: %s <threads> <arena-size> <color-shift>\n", | ||
211 | argv[0]); | ||
212 | ret = 1; | ||
213 | goto out; | ||
214 | } | ||
215 | |||
216 | err = xstrtol(argv[1], &strtol_val); | ||
217 | nr_threads = strtol_val; | ||
218 | err |= xstrtol(argv[2], &strtol_val); | ||
219 | arena_size = strtol_val; | ||
220 | err |= xstrtol(argv[3], &strtol_val); | ||
221 | color_shift = strtol_val; | ||
222 | if (err) { | ||
223 | debug_print("non-integer argument?\n"); | ||
224 | ret = 1; | ||
225 | goto out; | ||
226 | } | ||
227 | if (arena_size & PAGE_LOWER) { | ||
228 | debug_print("arena size not page multiple\n"); | ||
229 | ret = 1; | ||
230 | goto out; | ||
231 | } | ||
232 | |||
233 | pthread_state = malloc(nr_threads * sizeof(*pthread_state)); | ||
234 | if (!pthread_state) { | ||
235 | debug_print("could not malloc for state\n"); | ||
236 | ret = 1; | ||
237 | goto out; | ||
238 | } | ||
239 | |||
133 | CHECK(pthread_attr_init, &attr); | 240 | CHECK(pthread_attr_init, &attr); |
134 | CHECK(pthread_attr_setdetachstate, &attr, PTHREAD_CREATE_JOINABLE); | 241 | CHECK(pthread_attr_setdetachstate, &attr, PTHREAD_CREATE_JOINABLE); |
135 | CHECK(pthread_mutex_init, &ready_mutex, NULL); | 242 | CHECK(pthread_barrier_init, &barrier, NULL, nr_threads); |
136 | CHECK(pthread_cond_init, &ready_cond, NULL); | ||
137 | 243 | ||
138 | for (i = 0; i < NR_CPUS; i++) { | 244 | for (i = 0; i < nr_threads; i++) { |
139 | pthread_state[i].thread = i; | 245 | pthread_state[i].tid= i; |
140 | CHECK(pthread_create, &threads[i], &attr, thread_start, | 246 | CHECK(pthread_create, &pthread_state[i].thread, &attr, thread_start, |
141 | (void*)&pthread_state[i]); | 247 | (void*)&pthread_state[i]); |
142 | } | 248 | } |
143 | 249 | ||
144 | for (i = 0; i < NR_CPUS; i++) { | 250 | for (i = 0; i < nr_threads; i++) { |
145 | int *retval; | 251 | int *retval; |
146 | printf("join %d\n", i); | 252 | err = pthread_join(pthread_state[i].thread, (void**)&retval); |
147 | err = pthread_join(threads[i], (void**)&retval); | ||
148 | if (err) { | 253 | if (err) { |
149 | #ifdef DEBUG | 254 | debug_print("pthread_join failed\n"); |
150 | fprintf(stderr, "pthread_join failed\n"); | ||
151 | #endif | ||
152 | ret = err; | 255 | ret = err; |
153 | goto out; | 256 | goto out; |
154 | } | 257 | } |
155 | if (PTHREAD_CANCELED == retval || *retval) { | 258 | if (PTHREAD_CANCELED == retval || *retval) { |
156 | #ifdef DEBUG | 259 | debug_print("bad retval T%d\n", i); |
157 | fprintf(stderr, "T%d bad retval.\n", i); | ||
158 | #endif | ||
159 | ret = 1; | 260 | ret = 1; |
160 | } | 261 | } |
161 | } | 262 | } |
162 | 263 | ||
163 | CHECK(pthread_cond_destroy, &ready_cond); | 264 | CHECK(pthread_barrier_destroy, &barrier); |
164 | CHECK(pthread_attr_destroy, &attr); | 265 | CHECK(pthread_attr_destroy, &attr); |
165 | CHECK(pthread_mutex_destroy, &ready_mutex); | ||
166 | 266 | ||
167 | out: | 267 | out: |
168 | return ret; | 268 | return ret; |
diff --git a/bin/colortest.c b/bin/colortest.c index db552be..02a9169 100644 --- a/bin/colortest.c +++ b/bin/colortest.c | |||
@@ -36,8 +36,8 @@ static void check_memory(const char *start, const size_t len, const char expect) | |||
36 | } | 36 | } |
37 | } | 37 | } |
38 | 38 | ||
39 | void setup_pages(struct color_ctrl_page *ctrl, uint32_t start, | 39 | void setup_pages(struct color_ctrl_page *ctrl, uint16_t start, |
40 | uint32_t nr_pages, uint32_t stride) | 40 | uint16_t nr_pages, uint16_t stride) |
41 | { | 41 | { |
42 | int i; | 42 | int i; |
43 | for (i = 0; i < nr_pages; i++, start += stride) | 43 | for (i = 0; i < nr_pages; i++, start += stride) |
diff --git a/bin/rtspin.c b/bin/rtspin.c index ae76941..a6a8ac6 100644 --- a/bin/rtspin.c +++ b/bin/rtspin.c | |||
@@ -181,7 +181,7 @@ int main(int argc, char** argv) | |||
181 | double *exec_times = NULL; | 181 | double *exec_times = NULL; |
182 | double scale = 1.0; | 182 | double scale = 1.0; |
183 | task_class_t class = RT_CLASS_HARD; | 183 | task_class_t class = RT_CLASS_HARD; |
184 | int cur_job, num_jobs; | 184 | int cur_job, num_jobs = 0; |
185 | 185 | ||
186 | progname = argv[0]; | 186 | progname = argv[0]; |
187 | 187 | ||