aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile7
-rw-r--r--bin/color.c2
-rw-r--r--bin/colorbench.c37
-rw-r--r--bin/colortest.c1
-rw-r--r--bin/perfcounters.c27
-rw-r--r--bin/singlepage.c158
-rw-r--r--include/perfcounters.h10
7 files changed, 224 insertions, 18 deletions
diff --git a/Makefile b/Makefile
index 5527862..b4600fc 100644
--- a/Makefile
+++ b/Makefile
@@ -72,7 +72,7 @@ AR := ${CROSS_COMPILE}${AR}
72 72
73all = lib ${rt-apps} 73all = lib ${rt-apps}
74rt-apps = cycles base_task rt_launch rtspin release_ts measure_syscall \ 74rt-apps = cycles base_task rt_launch rtspin release_ts measure_syscall \
75 base_mt_task runtests colortest colorbench testcounters bespin 75 base_mt_task runtests colortest colorbench testcounters singlepage
76 76
77.PHONY: all lib clean dump-config TAGS tags cscope help 77.PHONY: all lib clean dump-config TAGS tags cscope help
78 78
@@ -236,6 +236,9 @@ lib-colortest = -static
236obj-colorbench = colorbench.o color.o perfcounters.o common.o 236obj-colorbench = colorbench.o color.o perfcounters.o common.o
237lib-colorbench = -lpthread -lrt -lgsl -lgslcblas 237lib-colorbench = -lpthread -lrt -lgsl -lgslcblas
238 238
239obj-singlepage = singlepage.o color.o perfcounters.o common.o
240lib-singlepage =
241
239obj-testcounters = testcounters.o 242obj-testcounters = testcounters.o
240lib-testcounters = 243lib-testcounters =
241 244
@@ -244,7 +247,7 @@ lib-testcounters =
244 247
245.SECONDEXPANSION: 248.SECONDEXPANSION:
246${rt-apps}: $${obj-$$@} liblitmus.a 249${rt-apps}: $${obj-$$@} liblitmus.a
247 $(CC) -o $@ $(LDFLAGS) ${ldf-$@} $(filter-out liblitmus.a,$+) $(LOADLIBS) $(LDLIBS) ${liblitmus-flags} ${lib-$@} 250 $(CC) -o $@ $(LDFLAGS) ${ldf-$@} $(filter-out liblitmus.a,$+) $(LOADLIBS) $(LDLIBS) ${lib-$@} ${liblitmus-flags}
248 251
249# ############################################################################## 252# ##############################################################################
250# Dependency resolution. 253# Dependency resolution.
diff --git a/bin/color.c b/bin/color.c
index 2ec97a4..c1753a4 100644
--- a/bin/color.c
+++ b/bin/color.c
@@ -21,7 +21,7 @@ static int map_file(const char* filename, void **addr, size_t size)
21 if (fd >= 0) { 21 if (fd >= 0) {
22 *addr = mmap(NULL, size, 22 *addr = mmap(NULL, size,
23 PROT_READ | PROT_WRITE, 23 PROT_READ | PROT_WRITE,
24 MAP_PRIVATE, 24 MAP_SHARED,
25 fd, 0); 25 fd, 0);
26 if (*addr == MAP_FAILED) 26 if (*addr == MAP_FAILED)
27 error = -1; 27 error = -1;
diff --git a/bin/colorbench.c b/bin/colorbench.c
index c91b731..ac0c01a 100644
--- a/bin/colorbench.c
+++ b/bin/colorbench.c
@@ -18,17 +18,25 @@
18#define DEBUG 1 18#define DEBUG 1
19#define NR_LOOPS 10 19#define NR_LOOPS 10
20 20
21#if 0
21/* Pound */ 22/* Pound */
22#define NR_CPUS 4 23#define NR_CPUS 4
23#define CACHE_SIZE_MB 8 24#define CACHE_SIZE_MB 8
24#define ASSOC 16 25#define ASSOC 16
25#define LINE_SIZE 64 26#define LINE_SIZE 64
27#endif
28
29/* Flare */
30#define NR_CPUS 1
31#define CACHE_SIZE_MB 3
32#define ASSOC 12
33#define LINE_SIZE 64
26 34
27#define CACHE_SIZE (CACHE_SIZE_MB * 1024 * 1024) 35#define CACHE_SIZE (CACHE_SIZE_MB * 1024 * 1024)
28#define TOTAL_COLORS (CACHE_SIZE / ASSOC / PAGE_SIZE) 36#define TOTAL_COLORS (CACHE_SIZE / ASSOC / PAGE_SIZE)
29 37
30/* number of colors we actually use */ 38/* number of colors we actually use (cannot be zero) */
31#define USE_COLORS (TOTAL_COLORS >> color_shift) 39#define USE_COLORS ({int v = TOTAL_COLORS >> color_shift; (v) ? v : 1; })
32 40
33/* how many adjacent pages of the same color we need to allocate */ 41/* how many adjacent pages of the same color we need to allocate */
34#define CONTIG_COLORS (ARENA_PAGES / USE_COLORS) 42#define CONTIG_COLORS (ARENA_PAGES / USE_COLORS)
@@ -76,7 +84,7 @@ static pthread_barrier_t barrier;
76static int nr_threads; 84static int nr_threads;
77static int arena_size; 85static int arena_size;
78static int color_shift; 86static int color_shift;
79//static int *page_line_order; 87static int *page_line_order;
80static int *arena_line_order; 88static int *arena_line_order;
81static struct perf_counter perf_counters[NR_CPUS * NR_PERF_COUNTERS]; 89static struct perf_counter perf_counters[NR_CPUS * NR_PERF_COUNTERS];
82 90
@@ -138,7 +146,6 @@ void sattolo(int *items, const int len)
138 * Starting at position 0 in the page_line_order means the cycle ends with 0. 146 * Starting at position 0 in the page_line_order means the cycle ends with 0.
139 * We use 0 in the arena to signify that we are done reading. 147 * We use 0 in the arena to signify that we are done reading.
140 */ 148 */
141#if 0
142static void init_arena_page_line_order(int *arena) 149static void init_arena_page_line_order(int *arena)
143{ 150{
144 int cur_page; 151 int cur_page;
@@ -168,7 +175,8 @@ static void init_arena_page_line_order(int *arena)
168 } 175 }
169 } 176 }
170} 177}
171#endif 178
179#if 0
172static void init_arena_line_order(int *arena) 180static void init_arena_line_order(int *arena)
173{ 181{
174 int cur_line; 182 int cur_line;
@@ -184,6 +192,7 @@ static void init_arena_line_order(int *arena)
184 arena[idx] = next_idx; 192 arena[idx] = next_idx;
185 } 193 }
186} 194}
195#endif
187 196
188static void setup_colors(struct pthread_state *state) 197static void setup_colors(struct pthread_state *state)
189{ 198{
@@ -262,8 +271,8 @@ int thread_init(struct pthread_state *state)
262 goto out; 271 goto out;
263 } 272 }
264 273
265 //init_arena_page_line_order(state->arena); 274 init_arena_page_line_order(state->arena);
266 init_arena_line_order(state->arena); 275 //init_arena_line_order(state->arena);
267 276
268 err = mlockall(MCL_CURRENT|MCL_FUTURE); 277 err = mlockall(MCL_CURRENT|MCL_FUTURE);
269 if (err) 278 if (err)
@@ -405,7 +414,7 @@ int main(int argc, char **argv)
405 } 414 }
406 415
407 pthread_state = malloc(nr_threads * sizeof(*pthread_state)); 416 pthread_state = malloc(nr_threads * sizeof(*pthread_state));
408 //page_line_order = malloc(PAGE_LINES * sizeof(*page_line_order)); 417 page_line_order = malloc(PAGE_LINES * sizeof(*page_line_order));
409 arena_line_order = malloc(ARENA_LINES * sizeof(*arena_line_order)); 418 arena_line_order = malloc(ARENA_LINES * sizeof(*arena_line_order));
410 //if (!pthread_state || !page_line_order) { 419 //if (!pthread_state || !page_line_order) {
411 if (!pthread_state || !arena_line_order) { 420 if (!pthread_state || !arena_line_order) {
@@ -420,9 +429,10 @@ int main(int argc, char **argv)
420 CHECK(pthread_attr_setdetachstate, &attr, PTHREAD_CREATE_JOINABLE); 429 CHECK(pthread_attr_setdetachstate, &attr, PTHREAD_CREATE_JOINABLE);
421 CHECK(pthread_barrier_init, &barrier, NULL, nr_threads); 430 CHECK(pthread_barrier_init, &barrier, NULL, nr_threads);
422 431
423 //sattolo(page_line_order, PAGE_LINES); 432 sattolo(page_line_order, PAGE_LINES);
424 sattolo(arena_line_order, ARENA_LINES); 433 //sattolo(arena_line_order, ARENA_LINES);
425 //sequential(page_line_order, PAGE_LINES); 434 //sequential(page_line_order, PAGE_LINES);
435 //sequential(arena_line_order, PAGE_LINES);
426 436
427 for (i = 0; i < nr_threads; i++) { 437 for (i = 0; i < nr_threads; i++) {
428 pthread_state[i].tid = i; 438 pthread_state[i].tid = i;
@@ -447,12 +457,15 @@ int main(int argc, char **argv)
447 CHECK(pthread_barrier_destroy, &barrier); 457 CHECK(pthread_barrier_destroy, &barrier);
448 CHECK(pthread_attr_destroy, &attr); 458 CHECK(pthread_attr_destroy, &attr);
449 459
460 printf("page size: %d\n", PAGE_SIZE);
461 printf("cache size: %d\n", CACHE_SIZE);
462 printf("total colors: %d\n", TOTAL_COLORS);
463 printf("use colors: %d\n", USE_COLORS);
464 printf("contiguous colors: %d\n", CONTIG_COLORS);
450 printf("arena size: %d\n", arena_size); 465 printf("arena size: %d\n", arena_size);
451 printf("color shift: %d\n", color_shift); 466 printf("color shift: %d\n", color_shift);
452 printf("arena pages: %d\n", ARENA_PAGES); 467 printf("arena pages: %d\n", ARENA_PAGES);
453 printf("arena lines: %d\n", ARENA_LINES); 468 printf("arena lines: %d\n", ARENA_LINES);
454 printf("use colors: %d\n", USE_COLORS);
455 printf("contiguous colors: %d\n", CONTIG_COLORS);
456 //print_perf_counters(); 469 //print_perf_counters();
457 470
458out: 471out:
diff --git a/bin/colortest.c b/bin/colortest.c
index 02a9169..bc66522 100644
--- a/bin/colortest.c
+++ b/bin/colortest.c
@@ -1,7 +1,6 @@
1#include <stdlib.h> 1#include <stdlib.h>
2#include <stdio.h> 2#include <stdio.h>
3#include <stdint.h> 3#include <stdint.h>
4
5#include <litmus/rt_param.h> 4#include <litmus/rt_param.h>
6 5
7#include "color.h" 6#include "color.h"
diff --git a/bin/perfcounters.c b/bin/perfcounters.c
index 6302164..975ee5b 100644
--- a/bin/perfcounters.c
+++ b/bin/perfcounters.c
@@ -39,7 +39,7 @@ struct perf_counter_setup {
39}; 39};
40 40
41#if 0 41#if 0
42/* these events are always zero */ 42/* on Pound, these events are always zero */
43static struct perf_fd perf_fds[] = { 43static struct perf_fd perf_fds[] = {
44 { 44 {
45 .fd = -1, 45 .fd = -1,
@@ -61,6 +61,8 @@ static struct perf_fd perf_fds[] = {
61}; 61};
62#endif 62#endif
63 63
64#if 0
65/* these are for Pound */
64static struct perf_counter_setup perf_setup[NR_PERF_COUNTERS] = { 66static struct perf_counter_setup perf_setup[NR_PERF_COUNTERS] = {
65#if 0 67#if 0
66 { 68 {
@@ -108,7 +110,30 @@ static struct perf_counter_setup perf_setup[NR_PERF_COUNTERS] = {
108#endif 110#endif
109 }, 111 },
110}; 112};
113#endif
111 114
115static struct perf_counter_setup perf_setup[NR_PERF_COUNTERS] = {
116 {
117 .name = "Linux LL Cache Read Miss",
118 .type = PERF_TYPE_HW_CACHE,
119 .config = ATTR_CONFIG_CACHE(LL, OP_READ, RESULT_MISS),
120#if 0
121 /* read misses */
122 .config = ATTR_CONFIG_CACHE(LL, OP_READ, RESULT_MISS),
123 /* write misses */
124 .config = ATTR_CONFIG_CACHE(LL, OP_WRITE, RESULT_MISS),
125 /* prefetch misses */
126 .config = ATTR_CONFIG_CACHE(LL, OP_PREFETCH, RESULT_MISS),
127#endif
128 },
129#if (2 == NR_PERF_COUNTERS)
130 {
131 .name = "Cycles",
132 .type = PERF_TYPE_HARDWARE,
133 .config = PERF_COUNT_HW_CPU_CYCLES,
134 },
135#endif
136};
112 137
113/* from kernel tools/perf/perf.h */ 138/* from kernel tools/perf/perf.h */
114int sys_perf_event_open(struct perf_event_attr *attr, pid_t pid, 139int sys_perf_event_open(struct perf_event_attr *attr, pid_t pid,
diff --git a/bin/singlepage.c b/bin/singlepage.c
new file mode 100644
index 0000000..376f55d
--- /dev/null
+++ b/bin/singlepage.c
@@ -0,0 +1,158 @@
1#include <stdint.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <sys/ioctl.h>
5
6#include <litmus/rt_param.h>
7
8#include "perfcounters.h"
9#include "color.h"
10#include "litmus.h"
11
12#define CPU 0
13#define NR_PAGES 10
14#define NR_LOOPS 10
15
16struct page {
17 struct page *ptr;
18 char _unused[PAGE_SIZE - sizeof(struct page*)];
19};
20
21/*
22 * Get a random number in [0, max). Not really a good way to do this.
23 */
24static int randrange(const int max)
25{
26 return (rand() / (RAND_MAX / max + 1));
27}
28
29/*
30 * Sattolo's algorithm makes a random cycle that includes all the elements
31 * in the items array.
32 */
33static void sattolo(int *items, const int len)
34{
35 int i;
36 /* first set up 0, 1, ..., n - 1 */
37 for (i = 0; i < len; i++)
38 items[i] = i;
39 /* note: i is now n */
40 while (1 < i--) {
41 /* 0 <= j < i */
42 int t, j = randrange(i);
43 t = items[i];
44 items[i] = items[j];
45 items[j] = t;
46 }
47}
48static struct page * do_read(struct page* page)
49{
50 struct page *old;
51 do {
52 old = page;
53 page = page->ptr;
54 } while (page);
55 return old;
56}
57
58static inline void get_counters(const struct perf_counter *pc, uint64_t *vals)
59{
60 read_perf_counter(&pc[0], &vals[0]);
61#if (2 == NR_PERF_COUNTERS)
62 read_perf_counter(&pc[1], &vals[1]);
63#endif
64}
65
66static void print_counters(uint64_t *vals, double div)
67{
68 int i;
69 for (i = 0; i < NR_PERF_COUNTERS; i++) {
70 printf("counter %d: %12lu div: %8.3f\n", i, vals[i], vals[i] / div);
71 }
72 printf("\n");
73}
74
75#define quit_on_err(err, msg) do { \
76 if (err) { \
77 fprintf(stderr, "error: " msg); \
78 goto out; \
79 } \
80} while (0)
81
82int main(int argc, char **argv)
83{
84 static struct perf_counter perf_counters[NR_PERF_COUNTERS];
85 struct color_ctrl_page *color_ctrl;
86 struct page *pages[NR_PAGES];
87 struct page *page_ptr;
88 int read_order[NR_PAGES];
89 uint64_t counter_vals[NR_PERF_COUNTERS];
90 int i, err = 0;
91
92 err = be_migrate_to(CPU);
93 quit_on_err(err, "migrate to cpu\n");
94
95 err = setup_cpu_perf(CPU, -1, perf_counters);
96 quit_on_err(err, "setup perf\n");
97
98 ioctl(perf_counters[0].fd, PERF_EVENT_IOC_DISABLE);
99 ioctl(perf_counters[0].fd, PERF_EVENT_IOC_RESET);
100
101
102 err = map_color_ctrl((void**)&color_ctrl);
103 quit_on_err(err, "map color ctrl\n");
104
105 color_ctrl->colors[0] = 0;
106
107 for (i = 0; i < NR_PAGES; i++) {
108 pages[i] = color_malloc(sizeof(*pages[i]));
109 if (!pages[i]) {
110 fprintf(stderr, "could not color malloc\n");
111 err = -1;
112 goto out;
113 }
114 }
115
116 sattolo(read_order, NR_PAGES);
117
118 ioctl(perf_counters[0].fd, PERF_EVENT_IOC_ENABLE);
119
120 for (i = 0; i < NR_PAGES; i++) {
121 if (0 != read_order[i]) {
122 /* not the last element */
123 pages[i]->ptr = pages[read_order[i]];
124 } else {
125 /* last element should be NULL (terminate the cycle) */
126 pages[i]->ptr = NULL;
127 }
128 }
129
130 get_counters(perf_counters, counter_vals);
131 print_counters(counter_vals, NR_PAGES);
132 ioctl(perf_counters[0].fd, PERF_EVENT_IOC_RESET);
133
134 page_ptr = do_read(pages[0]);
135 get_counters(perf_counters, counter_vals);
136 print_counters(counter_vals, NR_PAGES);
137 ioctl(perf_counters[0].fd, PERF_EVENT_IOC_RESET);
138
139 page_ptr = do_read(pages[0]);
140 get_counters(perf_counters, counter_vals);
141 print_counters(counter_vals, NR_PAGES);
142 ioctl(perf_counters[0].fd, PERF_EVENT_IOC_RESET);
143
144 page_ptr = do_read(pages[0]);
145 get_counters(perf_counters, counter_vals);
146 print_counters(counter_vals, NR_PAGES);
147 ioctl(perf_counters[0].fd, PERF_EVENT_IOC_RESET);
148
149 for (i = 0; i < NR_LOOPS; i++) {
150 page_ptr = do_read(pages[0]);
151 }
152 get_counters(perf_counters, counter_vals);
153 print_counters(counter_vals, NR_PAGES * NR_LOOPS);
154 ioctl(perf_counters[0].fd, PERF_EVENT_IOC_DISABLE);
155
156out:
157 return err;
158}
diff --git a/include/perfcounters.h b/include/perfcounters.h
index 03f94fb..0329921 100644
--- a/include/perfcounters.h
+++ b/include/perfcounters.h
@@ -5,7 +5,15 @@
5 5
6#include "../../litmus-rt/include/linux/perf_event.h" 6#include "../../litmus-rt/include/linux/perf_event.h"
7 7
8#define NR_PERF_COUNTERS 4 8/* on Pound */
9//#define NR_PERF_COUNTERS 4
10
11/*
12 * Flare: 1 gets you the L2 read misses and 2 gets you that plus the
13 * CPU clock counter. However, accessing the CPU clock will add misses
14 * when you go to read the performance counters, so I don't use it.
15 */
16#define NR_PERF_COUNTERS 1
9 17
10/* 18/*
11 * Retain this information with a performance counter file descriptor. 19 * Retain this information with a performance counter file descriptor.