static void item_preface(struct item_data *data, const struct p_bench_item *item) { invalidate_data_cache(); data->start = platform_clock(); }
static void item_done(struct item_data *data, const struct p_benchmark_specification *spec, const char *name) { assert(name != NULL); assert(name[0] != 0); platform_clock_t now = platform_clock(); (void)printf("%s size: %zu duration: ", name, spec->current_size); platform_print_duration(data->start, now); (void)printf("\n"); }
int saucy_with_graph(struct amorph_graph *g, int smode, int qmode, int rep, int coarsest, int* result) { struct saucy *s; long cpu_time; int i, n; FILE *f; quiet_mode = qmode; stats_mode = smode; repeat = rep; /* Repeating is for benchmarking */ if (repeat > 1) quiet_mode = stats_mode = 1; n = g->sg.n; /* Allocate some memory to facilitate printing */ marks = (char *) calloc(n, sizeof(char)); if (!marks) { die("out of memory"); } /* Allocate saucy space */ s = saucy_alloc(n); if (s == NULL) { die("saucy initialization failed"); } /* Set up the alarm for timeouts */ if (timeout > 0) { platform_set_timer(timeout, timeout_handler); } /* Print statistics when signaled */ platform_set_user_signal(stats_handler); /* Start timing */ cpu_time = platform_clock(); /* Run the search */ for (i = 0; i < repeat; ++i) { int* part = saucy_search(s, &g->sg, digraph_mode, g->colors, on_automorphism, g, &stats, coarsest); memcpy(result, part, n * sizeof(int)); if (coarsest) continue; for (int ii = 0; ii < n; ii++) { int rep; for (rep = result[ii]; rep != result[rep]; rep = result[rep]); result[ii] = rep; } } /* Finish timing */ cpu_time = platform_clock() - cpu_time; if (gap_mode && !quiet_mode) printf("\n]\n"); /* Warn if timeout */ if (timeout_flag) warn("search timed out"); /* Print out stats if requested */ if (stats_mode) { fflush(stdout); f = quiet_mode ? stdout : stderr; fprintf(f, "input file = %s\n", filename); if (g->stats) g->stats(g, f); fprintf(f, "vertices = %d\n", n); fprintf(f, "edges = %d\n", g->sg.e); print_stats(f); fprintf(f, "cpu time (s) = %.2f\n", divide(cpu_time, PLATFORM_CLOCKS_PER_SEC)); } /* Cleanup */ saucy_free(s); g->free(g); free(marks); /* That's it, have a nice day */ return EXIT_SUCCESS; }
int main(int argc, char **argv) { struct saucy *s; struct amorph_graph *g = NULL; long cpu_time; int i, n; FILE *f; /* Option handling */ parse_arguments(&argc, &argv, options); if (argc < 1) die("missing filename"); if (argc > 1) die("trailing arguments"); filename = *argv; /* Repeating is for benchmarking */ if (repeat > 1) quiet_mode = stats_mode = 1; if (gap_mode + cnf_mode + digraph_mode > 1) { die("--cnf, --digraph, and --shatter are mutually exclusive"); } /* Read the input file */ if (gap_mode) { g = amorph_read_gap(filename); } else if (cnf_mode) { g = amorph_read_dimacs(filename); } else { g = amorph_read(filename, digraph_mode); } if (!g) { die("unable to read input file"); } n = g->sg.n; /* Allocate some memory to facilitate printing */ marks = (char *) calloc(n, sizeof(char)); if (!marks) { die("out of memory"); } /* Allocate saucy space */ s = saucy_alloc(n); if (s == NULL) { die("saucy initialization failed"); } /* Set up the alarm for timeouts */ if (timeout > 0) { platform_set_timer(timeout, timeout_handler); } /* Print statistics when signaled */ platform_set_user_signal(stats_handler); /* Start timing */ cpu_time = platform_clock(); /* Run the search */ for (i = 0; i < repeat; ++i) { int* part = saucy_search(s, &g->sg, digraph_mode, g->colors, on_automorphism, g, &stats, 0); printf("partition\n"); for (int ii = 0; ii < n; ii++) printf("%d -> %d\n",ii,part[ii]); printf("\n"); } /* Finish timing */ cpu_time = platform_clock() - cpu_time; if (gap_mode && !quiet_mode) printf("\n]\n"); /* Warn if timeout */ if (timeout_flag) warn("search timed out"); /* Print out stats if requested */ if (stats_mode) { fflush(stdout); f = quiet_mode ? stdout : stderr; fprintf(f, "input file = %s\n", filename); if (g->stats) g->stats(g, f); fprintf(f, "vertices = %d\n", n); fprintf(f, "edges = %d\n", g->sg.e); print_stats(f); fprintf(f, "cpu time (s) = %.2f\n", divide(cpu_time, PLATFORM_CLOCKS_PER_SEC)); } /* Cleanup */ saucy_free(s); g->free(g); free(marks); /* That's it, have a nice day */ return EXIT_SUCCESS; }
static void item_preface(struct item_data *data, const struct p_bench_item *item) { data->start = platform_clock(); }
struct item_data item_bench(const struct p_bench_item *item, struct p_bench_specification *spec) { struct item_data data, best = { .end = ~(0ULL) }; uint64_t item_start_time = platform_clock(); /* Warm up caches, branch predictors etc. */ /* Calculate inner loop. */ int inner_loop; data.start = platform_clock(); for (int i = 0; i < 50; i++) item->benchmark(spec); data.end = platform_clock(); { float tmp = data.end - data.start; tmp /= 50.0f; /* 50k us seems to work */ tmp = 50000.0f / tmp; inner_loop = ceilf(tmp); } /* Repeat tests to get more stable results between runs */ while (true) { /* Measure 10 iterations so the clocksource's resolution doesn't * play tricks on us */ data.start = platform_clock(); for (int j = 0; j < inner_loop; j++) item->benchmark(spec); data.end = platform_clock(); /* Use best measurement */ if (best.end - best.start > data.end - data.start) best = data; /* Test each function for 1/2 second */ if (data.end - item_start_time >= 500000000ULL) break; } { /* Adjust for iterations in inner loop above */ float tmp = best.end - best.start; tmp /= (float) inner_loop; best.end = best.start + tmp; } return best; } int main(void) { struct p_bench_specification spec = { 0 }; char *raw_mem = NULL; spec.current_size = MAX_ELEMS; setup_memory(&spec.mem, &raw_mem, spec.current_size); bench_printf(";name, size, duration (ns)\n"); for (const struct p_bench_item *item = benchmark_items; item->name != NULL; ++item) { struct item_data best; bool consistent = false; best = item_bench(item, &spec); for (int tries = 0; tries < 50; tries++) { struct item_data snd; float fst_time, snd_time; /* Benchmark again ... */ snd = item_bench(item, &spec); fst_time = best.end - best.start; snd_time = snd.end - snd.start; /* ... and start over if results deviate too much */ if (fst_time / snd_time < 0.995 || snd_time / fst_time < 0.995) { /* Take average so abnormally low results converge over time */ best.end += (snd_time - fst_time) / 2.0f; usleep(100000); continue; } if (fst_time > snd_time) best = snd; consistent = true; break; } if (!consistent) { fprintf(stderr, ";WARNING: %s not consistent\n", item->name); fflush(stderr); } item_done(&best, &spec, item->name); } return EXIT_SUCCESS; } #else /* __epiphany__ */ int main(void) { struct p_bench_specification spec = { 0 }; char *raw_mem = NULL; spec.current_size = MAX_ELEMS; uint32_t nbench = 0; setup_memory(&spec.mem, &raw_mem, spec.current_size); bench_printf(";name, size, duration (ns)\n"); for (const struct p_bench_item *item = benchmark_items; item->name != NULL; ++item) { struct item_data data; data.start = platform_clock(); item->benchmark(&spec); data.end = platform_clock(); strcpy(epiphany_results[nbench].name, item->name); epiphany_results[nbench].ns = data.end - data.start; epiphany_results[nbench].size = (uint64_t) spec.current_size; nbench++; epiphany_status->nbench = nbench; } epiphany_status->done = 1; return EXIT_SUCCESS; } #endif static void setup_output_pointers(struct p_bench_raw_memory *mem, void *p) { /* Assume largest type is 64 bits */ /* TODO: All pointers point to same memory region so output will be bogus */ mem->o1.p_u64 = p; mem->o2.p_u64 = p; mem->o3.p_u64 = p; mem->o4.p_u64 = p; }