#include #include #include #include #include #include "asm/cacheparams.h" #include "asm/cycles.h" #include "litmus.h" #include "color.h" #define CPU 1 #define NR_LOOPS 1000 #define MULT 699050667 #define SHIFT 24 /* * Get a random number in [0, max). Not really a good way to do this. */ static int randrange(const int max) { return (rand() / (RAND_MAX / max + 1)); } static inline int64_t cyc2ns(cycles_t cycles) { return ((uint64_t) cycles * MULT) >> SHIFT; } static unsigned long long rdclock(void) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return ts.tv_sec * 1000000000ULL + ts.tv_nsec; } #define quit_on_err(err, msg) do { \ if (err) { \ fprintf(stderr, "error: " msg); \ goto out; \ } \ } while (0) int main(int argc, char **argv) { struct color_ctrl_page *color_ctrl; cycles_t start, end; int err = 0, i, j, wss, nr_colors; uint32_t sum = 0, *data; uint32_t *malloc_data; double nsec_avg, m_nsec_avg; unsigned long long m_start, m_end; if (3 > argc) { fprintf(stderr, "%s: [wss] [nr-colors]\n", argv[0]); err = 1; goto out; } wss = atoi(argv[1]); quit_on_err(0 != wss % PAGE_SIZE, "bad WSS\n"); nr_colors = atoi(argv[2]); quit_on_err(1 > nr_colors || 16 < nr_colors, "bad NR-COLORS\n"); quit_on_err(0 != (wss / PAGE_SIZE) % nr_colors, "nr_colors does not divide pages needed\n"); err = be_migrate_to(CPU); quit_on_err(err, "migrate to CPU\n"); color_ctrl = get_color_ctrl(); quit_on_err(!color_ctrl, "map color ctrl\n"); for (i = 0; i < nr_colors; i++) { color_ctrl->pages[i] = wss / PAGE_SIZE / nr_colors; color_ctrl->colors[i] = i; fprintf(stderr, "[%3d] pages=%3d color=%3d\n", i, color_ctrl->pages[i], color_ctrl->colors[i]); } data = color_malloc(wss); quit_on_err(!data, "color malloc failed\n"); malloc_data = malloc(wss); quit_on_err(!malloc_data, "regular malloc failed\n"); fprintf(stderr, "color data: %p regular data: %p\n", data, malloc_data); fflush(stderr); sleep(2); for (i = 0; i < wss / sizeof(*data); i += CACHE_LINE_SIZE / sizeof(*data)) { int randint = randrange(RAND_MAX - 1); data[i] = randint; malloc_data[i] = randint; } fprintf(stderr, "color data: %p regular data: %p\n", data, malloc_data); fflush(stderr); sleep(2); m_start = rdclock(); null_call(&start); for (i = 0; i < NR_LOOPS; i++) { for (j = 0; j < wss / sizeof(*data); j += 128 / sizeof(*data)) { sum += data[j]; } } null_call(&end); m_end = rdclock(); nsec_avg = cyc2ns(end - start) / ((double)NR_LOOPS); m_nsec_avg = (m_end - m_start) / ((double)NR_LOOPS); printf("%7d, %2d, %8.3f, %8.3f\n", wss, nr_colors, nsec_avg, nsec_avg / (wss / PAGE_SIZE)); printf("%7d, %2d, %8.3f, %8.3f\n", wss, nr_colors, m_nsec_avg, m_nsec_avg / (wss / PAGE_SIZE)); m_start = rdclock(); null_call(&start); for (i = 0; i < NR_LOOPS; i++) { for (j = 0; j < wss / sizeof(*malloc_data); j += 128 / sizeof(*data)) { sum += malloc_data[j]; } } null_call(&end); m_end = rdclock(); nsec_avg = cyc2ns(end - start) / ((double)NR_LOOPS); m_nsec_avg = (m_end - m_start) / ((double)NR_LOOPS); printf("%7d, %2d, %8.3f, %8.3f\n", wss, nr_colors, nsec_avg, nsec_avg / (wss / PAGE_SIZE)); printf("%7d, %2d, %8.3f, %8.3f\n", wss, nr_colors, m_nsec_avg, m_nsec_avg / (wss / PAGE_SIZE)); fprintf(stderr, "sum: %u\n", sum); out: return err; }