aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Kenna <cjk@cs.unc.edu>2012-04-11 00:53:24 -0400
committerChristopher Kenna <cjk@cs.unc.edu>2012-04-11 00:53:24 -0400
commitb0355b8cc0609be264042c5570e8c13078888636 (patch)
tree462ddf6a3de3016f97dfac19b62879eb52ac62f0
parent041df061efacf3a8e83edb47ac4db37e67e1a258 (diff)
updates to benchmarking program
-rw-r--r--bin/colorbench.c220
-rw-r--r--bin/colortest.c4
-rw-r--r--bin/rtspin.c2
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
18struct pthread_state { 46struct 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
25static pthread_mutex_t ready_mutex; 55static pthread_barrier_t barrier;
26static pthread_cond_t ready_cond; 56static int nr_threads;
27static int nr_ready; 57static int arena_size;
28static int arena_size = 5 * PAGE_SIZE; 58static 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)) 72static 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
84static 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
32static int loop_once(struct pthread_state *state) 93static 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
40int thread_init(struct pthread_state *state) 101int 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 }
81out: 139out:
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
91void * thread_start(void *data) 153void * 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 }
114out: 168out:
115 pthread_exit(&state->retval); 169 pthread_exit(&state->retval);
116} 170}
117 171
118static struct pthread_state pthread_state[NR_CPUS]; 172int 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;
189out:
190 return err;
191}
192
193static 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
126int main(int argc, char **argv) 203int 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
167out: 267out:
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
39void setup_pages(struct color_ctrl_page *ctrl, uint32_t start, 39void 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