aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Kenna <cjk@cs.unc.edu>2012-12-05 17:01:39 -0500
committerChristopher Kenna <cjk@cs.unc.edu>2012-12-05 17:01:39 -0500
commit509649ed5f774efdaa6badb6cdcf8282e917ffd4 (patch)
tree93a3d9acd5eda9027127688c764e79ca82a64e55
parentfc8bf9b972edbb049af7f3980f8026b83d27b4fd (diff)
Add two programs.wip-color
-rw-r--r--bin/armsinglepage.c238
-rw-r--r--bin/wss.c139
2 files changed, 377 insertions, 0 deletions
diff --git a/bin/armsinglepage.c b/bin/armsinglepage.c
new file mode 100644
index 0000000..cf619b7
--- /dev/null
+++ b/bin/armsinglepage.c
@@ -0,0 +1,238 @@
1#include <stdint.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <sys/ioctl.h>
5#include <unistd.h>
6#include <inttypes.h>
7
8#include "asm/cacheparams.h"
9
10#include <litmus/rt_param.h>
11
12#include "perfcounters.h"
13
14#include "color.h"
15#include "litmus.h"
16
17#define CPU 1
18#define NR_LOOPS 10000
19
20static int pages_per_datum;
21/* Number of pages in a "data" element, each with same color. */
22
23static int nr_data;
24/* Number of "data" elements. */
25
26
27struct page;
28#define NR_PAGE_INTS ((PAGE_SIZE - CACHE_LINE_SIZE) / sizeof(uint32_t))
29struct page {
30 struct page *ptr;
31 struct page *_unused[CACHE_LINE_SIZE / sizeof(struct page*) - 1];
32 uint32_t ints[NR_PAGE_INTS];
33};
34
35struct datum {
36 struct page *pages;
37};
38
39/*
40 * Get a random number in [0, max). Not really a good way to do this.
41 */
42static int randrange(const int max)
43{
44 return (rand() / (RAND_MAX / max + 1));
45}
46
47static void setup_page_ints(struct page *page)
48{
49 int i;
50
51 for (i = 0; i < NR_PAGE_INTS; i++) {
52 page->ints[i] = randrange(RAND_MAX);
53 }
54}
55
56/*
57 * Sattolo's algorithm makes a random cycle that includes all the elements
58 * in the items array.
59 */
60static void sattolo(int *items, const int len)
61{
62 int i;
63 /* first set up 0, 1, ..., n - 1 */
64 for (i = 0; i < len; i++)
65 items[i] = i;
66 /* note: i is now n */
67 while (1 < i--) {
68 /* 0 <= j < i */
69 int t, j = randrange(i);
70 t = items[i];
71 items[i] = items[j];
72 items[j] = t;
73 }
74}
75
76static uint32_t get_sum(struct page *page)
77{
78 uint32_t sum = 0;
79 int i;
80
81 for (i = 0; i < NR_PAGE_INTS; i += CACHE_LINE_SIZE / sizeof(uint32_t)) {
82 sum += page->ints[i];
83 }
84 return sum;
85}
86
87static uint32_t do_read(struct page* page)
88{
89 struct page *old;
90 uint32_t sum = 0;
91
92 do {
93 old = page;
94 page = page->ptr;
95 sum += get_sum(old);
96 } while (page);
97 return sum;
98}
99
100#define MULT 699050667
101#define SHIFT 24
102
103static inline int64_t clocksource_cyc2ns(cycles_t cycles, uint32_t mult, uint32_t shift)
104{
105 return ((uint64_t) cycles * mult) >> shift;
106}
107
108#if 0
109static void print_difference(const cycles_t start, const cycles_t end)
110{
111 cycles_t diff = end - start;
112
113 printf("difference: %10llu = %10llu ns\n", diff, clocksource_cyc2ns(diff, MULT, SHIFT));
114}
115#endif
116
117#define quit_on_err(err, msg) do { \
118 if (err) { \
119 fprintf(stderr, "error: " msg); \
120 goto out; \
121 } \
122} while (0)
123
124int main(int argc, char **argv)
125{
126 struct color_ctrl_page *color_ctrl;
127 struct datum *data;
128 int *read_order;
129 int i, j, err = 0;
130 cycles_t start, end;
131 uint32_t sum = 0;
132 int64_t nanoseconds;
133 double avg_nanoseconds;
134
135 quit_on_err(PAGE_SIZE != sizeof(struct page),
136 "PAGE_SIZE != sizeof(struct page)\n");
137
138 if (3 > argc) {
139 fprintf(stderr, "%s: [pages-per-datum] [nr-data]\n", argv[0]);
140 err = 1;
141 goto out;
142 }
143
144 pages_per_datum = atoi(argv[1]);
145 nr_data = atoi(argv[2]);
146
147 quit_on_err(0 == nr_data || 0 == pages_per_datum, "zero argument\n");
148 quit_on_err(16 < nr_data, "too many nr_data\n");
149
150 read_order = malloc(pages_per_datum * sizeof(*read_order));
151 data = malloc(nr_data * sizeof(*data));
152 quit_on_err(!read_order || !data, "malloc\n");
153
154 err = be_migrate_to(CPU);
155 quit_on_err(err, "migrate to cpu\n");
156
157 color_ctrl = get_color_ctrl();
158 if (!color_ctrl) {
159 fprintf(stderr, "could not map color ctrl\n");
160 err = -1;
161 goto out;
162 }
163
164 /* Always allocating this many pages of the same color. */
165 color_ctrl->pages[0] = pages_per_datum;
166
167 for (i = 0; i < nr_data; i++) {
168 const unsigned nr_bytes = sizeof(data[i].pages[0]) * pages_per_datum;
169
170 /* give each datum its own color (XXX no checks to ensure not >
171 * NR_COLORS!) */
172
173 color_ctrl->colors[0] = i;
174 fprintf(stderr, "color_mallocing %u bytes\n", nr_bytes);
175 data[i].pages = color_malloc(nr_bytes);
176 if (!data[i].pages) {
177 fprintf(stderr, "could not color malloc\n");
178 err = -1;
179 goto out;
180 }
181 }
182
183 sattolo(read_order, pages_per_datum);
184
185 for (i = 0; i < nr_data; i++) {
186 for (j = 0; j < pages_per_datum; j++) {
187 if (0 != read_order[j]) {
188 /* not the last element */
189 data[i].pages[j].ptr = &(data[i].pages[read_order[j]]);
190 } else {
191 /* last element in pages inside of datum walk */
192 if (nr_data - 1 == i) {
193 /* last element globally */
194 data[i].pages[j].ptr = NULL;
195 } else {
196 /* jump to next datum */
197 data[i].pages[j].ptr = &(data[i + 1].pages[0]);
198 }
199 }
200
201 setup_page_ints(&(data[i].pages[j]));
202 }
203 }
204
205#if 0
206 null_call(&start);
207 null_call(&end);
208 print_difference(start, end);
209
210 null_call(&start);
211 sum += do_read(data[0].pages);
212 null_call(&end);
213 print_difference(start, end);
214
215 null_call(&start);
216 sum += do_read(data[0].pages);
217 null_call(&end);
218 print_difference(start, end);
219
220 null_call(&start);
221 sum += do_read(data[0].pages);
222 null_call(&end);
223 print_difference(start, end);
224#endif
225
226 null_call(&start);
227 for (i = 0; i < NR_LOOPS; i++) {
228 sum += do_read(data[0].pages);
229 }
230 null_call(&end);
231 nanoseconds = clocksource_cyc2ns(end - start, MULT, SHIFT);
232 avg_nanoseconds = ((double)nanoseconds) / NR_LOOPS;
233 printf("%3d, %10.3f, %10.3f\n", nr_data, avg_nanoseconds,
234 avg_nanoseconds / (nr_data * pages_per_datum));
235
236out:
237 return err;
238}
diff --git a/bin/wss.c b/bin/wss.c
new file mode 100644
index 0000000..3e1ec13
--- /dev/null
+++ b/bin/wss.c
@@ -0,0 +1,139 @@
1#include <stdint.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <time.h>
5#include <unistd.h>
6
7#include "asm/cacheparams.h"
8#include "asm/cycles.h"
9
10#include "litmus.h"
11#include "color.h"
12
13#define CPU 1
14#define NR_LOOPS 1000
15
16#define MULT 699050667
17#define SHIFT 24
18
19/*
20 * Get a random number in [0, max). Not really a good way to do this.
21 */
22static int randrange(const int max)
23{
24 return (rand() / (RAND_MAX / max + 1));
25}
26
27static inline int64_t cyc2ns(cycles_t cycles)
28{
29 return ((uint64_t) cycles * MULT) >> SHIFT;
30}
31
32static unsigned long long rdclock(void)
33{
34 struct timespec ts;
35 clock_gettime(CLOCK_MONOTONIC, &ts);
36 return ts.tv_sec * 1000000000ULL + ts.tv_nsec;
37}
38
39#define quit_on_err(err, msg) do { \
40 if (err) { \
41 fprintf(stderr, "error: " msg); \
42 goto out; \
43 } \
44} while (0)
45
46int main(int argc, char **argv)
47{
48 struct color_ctrl_page *color_ctrl;
49 cycles_t start, end;
50 int err = 0, i, j, wss, nr_colors;
51 uint32_t sum = 0, *data;
52 uint32_t *malloc_data;
53 double nsec_avg, m_nsec_avg;
54 unsigned long long m_start, m_end;
55
56 if (3 > argc) {
57 fprintf(stderr, "%s: [wss] [nr-colors]\n", argv[0]);
58 err = 1;
59 goto out;
60 }
61
62 wss = atoi(argv[1]);
63 quit_on_err(0 != wss % PAGE_SIZE, "bad WSS\n");
64
65 nr_colors = atoi(argv[2]);
66 quit_on_err(1 > nr_colors || 16 < nr_colors, "bad NR-COLORS\n");
67
68 quit_on_err(0 != (wss / PAGE_SIZE) % nr_colors, "nr_colors does not divide pages needed\n");
69
70 err = be_migrate_to(CPU);
71 quit_on_err(err, "migrate to CPU\n");
72
73 color_ctrl = get_color_ctrl();
74 quit_on_err(!color_ctrl, "map color ctrl\n");
75
76 for (i = 0; i < nr_colors; i++) {
77 color_ctrl->pages[i] = wss / PAGE_SIZE / nr_colors;
78 color_ctrl->colors[i] = i;
79 fprintf(stderr, "[%3d] pages=%3d color=%3d\n", i,
80 color_ctrl->pages[i], color_ctrl->colors[i]);
81 }
82 data = color_malloc(wss);
83 quit_on_err(!data, "color malloc failed\n");
84
85 malloc_data = malloc(wss);
86 quit_on_err(!malloc_data, "regular malloc failed\n");
87
88 fprintf(stderr, "color data: %p regular data: %p\n", data, malloc_data);
89 fflush(stderr);
90 sleep(2);
91
92 for (i = 0; i < wss / sizeof(*data); i += CACHE_LINE_SIZE / sizeof(*data)) {
93 int randint = randrange(RAND_MAX - 1);
94 data[i] = randint;
95 malloc_data[i] = randint;
96 }
97
98 fprintf(stderr, "color data: %p regular data: %p\n", data, malloc_data);
99 fflush(stderr);
100 sleep(2);
101
102 m_start = rdclock();
103 null_call(&start);
104 for (i = 0; i < NR_LOOPS; i++) {
105 for (j = 0; j < wss / sizeof(*data); j += 128 / sizeof(*data))
106 {
107 sum += data[j];
108 }
109 }
110 null_call(&end);
111 m_end = rdclock();
112
113 nsec_avg = cyc2ns(end - start) / ((double)NR_LOOPS);
114 m_nsec_avg = (m_end - m_start) / ((double)NR_LOOPS);
115 printf("%7d, %2d, %8.3f, %8.3f\n", wss, nr_colors, nsec_avg, nsec_avg / (wss / PAGE_SIZE));
116 printf("%7d, %2d, %8.3f, %8.3f\n", wss, nr_colors, m_nsec_avg, m_nsec_avg / (wss / PAGE_SIZE));
117
118
119 m_start = rdclock();
120 null_call(&start);
121 for (i = 0; i < NR_LOOPS; i++) {
122 for (j = 0; j < wss / sizeof(*malloc_data); j += 128 / sizeof(*data))
123 {
124 sum += malloc_data[j];
125 }
126 }
127 null_call(&end);
128 m_end = rdclock();
129
130 nsec_avg = cyc2ns(end - start) / ((double)NR_LOOPS);
131 m_nsec_avg = (m_end - m_start) / ((double)NR_LOOPS);
132 printf("%7d, %2d, %8.3f, %8.3f\n", wss, nr_colors, nsec_avg, nsec_avg / (wss / PAGE_SIZE));
133 printf("%7d, %2d, %8.3f, %8.3f\n", wss, nr_colors, m_nsec_avg, m_nsec_avg / (wss / PAGE_SIZE));
134
135
136 fprintf(stderr, "sum: %u\n", sum);
137out:
138 return err;
139}