static void do_one_test (impl_t *impl, void *dst, const void *src, int c, size_t len, size_t n) { void *expect = len > n ? NULL : (char *) dst + len; size_t i, iters = INNER_LOOP_ITERS; timing_t start, stop, cur; if (CALL (impl, dst, src, c, n) != expect) { error (0, 0, "Wrong result in function %s %p %p", impl->name, CALL (impl, dst, src, c, n), expect); ret = 1; return; } if (memcmp (dst, src, len > n ? n : len) != 0) { error (0, 0, "Wrong result in function %s", impl->name); ret = 1; return; } TIMING_NOW (start); for (i = 0; i < iters; ++i) { CALL (impl, dst, src, c, n); } TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); TIMING_PRINT_MEAN ((double) cur, (double) iters); }
static void do_one_test (impl_t *impl, const CHAR *s, size_t exp_len) { size_t len = CALL (impl, s), i, iters = INNER_LOOP_ITERS; timing_t start, stop, cur; if (len != exp_len) { error (0, 0, "Wrong result in function %s %zd %zd", impl->name, len, exp_len); ret = 1; return; } TIMING_NOW (start); for (i = 0; i < iters; ++i) { CALL (impl, s); } TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); TIMING_PRINT_MEAN ((double) cur, (double) iters); }
static void do_one_test (impl_t *impl, const char *s, const char *rej, RES_TYPE exp_res) { RES_TYPE res = CALL (impl, s, rej); size_t i, iters = INNER_LOOP_ITERS; timing_t start, stop, cur; if (res != exp_res) { error (0, 0, "Wrong result in function %s %p %p", impl->name, (void *) res, (void *) exp_res); ret = 1; return; } TIMING_NOW (start); for (i = 0; i < iters; ++i) { CALL (impl, s, rej); } TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); TIMING_PRINT_MEAN ((double) cur, (double) iters); }
static void do_one_test (impl_t *impl, const CHAR *s, int c, size_t n, CHAR *exp_res) { CHAR *res = CALL (impl, s, c, n); size_t i, iters = INNER_LOOP_ITERS; timing_t start, stop, cur; if (res != exp_res) { error (0, 0, "Wrong result in function %s %p %p", impl->name, res, exp_res); ret = 1; return; } TIMING_NOW (start); for (i = 0; i < iters; ++i) { CALL (impl, s, c, n); } TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); TIMING_PRINT_MEAN ((double) cur, (double) iters); }
static void do_one_test (impl_t *impl, CHAR *dst, const CHAR *src, size_t len __attribute__((unused))) { size_t i, iters = INNER_LOOP_ITERS; timing_t start, stop, cur; if (CALL (impl, dst, src) != STRCPY_RESULT (dst, len)) { error (0, 0, "Wrong result in function %s %p %p", impl->name, CALL (impl, dst, src), STRCPY_RESULT (dst, len)); ret = 1; return; } if (STRCMP (dst, src) != 0) { error (0, 0, "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"", impl->name, dst, src); ret = 1; return; } TIMING_NOW (start); for (i = 0; i < iters; ++i) { CALL (impl, dst, src); } TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); TIMING_PRINT_MEAN ((double) cur, (double) iters); }
static void do_one_test (impl_t *impl, const char *s1, const char *s2, int exp_result) { size_t i, iters = INNER_LOOP_ITERS; timing_t start, stop, cur; int result = CALL (impl, s1, s2); if ((exp_result == 0 && result != 0) || (exp_result < 0 && result >= 0) || (exp_result > 0 && result <= 0)) { error (0, 0, "Wrong result in function %s %d %d", impl->name, result, exp_result); ret = 1; return; } TIMING_NOW (start); for (i = 0; i < iters; ++i) { CALL (impl, s1, s2); } TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); TIMING_PRINT_MEAN ((double) cur, (double) iters); }
static void do_one_test (impl_t *impl, char *dst, const char *src, size_t len, size_t dlen) { char *res; size_t i, iters = INNER_LOOP_ITERS; timing_t start, stop, cur; if (dlen <= len) { if (impl->test == 1) return; chk_fail_ok = 1; if (setjmp (chk_fail_buf) == 0) { res = CALL (impl, dst, src, dlen); printf ("*** Function %s (%zd; %zd) did not __chk_fail\n", impl->name, len, dlen); chk_fail_ok = 0; ret = 1; } return; } else res = CALL (impl, dst, src, dlen); if (res != STRCPY_RESULT (dst, len)) { printf ("Wrong result in function %s %p %p\n", impl->name, res, STRCPY_RESULT (dst, len)); ret = 1; return; } if (strcmp (dst, src) != 0) { printf ("Wrong result in function %s dst \"%s\" src \"%s\"\n", impl->name, dst, src); ret = 1; return; } TIMING_NOW (start); for (i = 0; i < iters; ++i) { CALL (impl, dst, src, dlen); } TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); TIMING_PRINT_MEAN ((double) cur, (double) iters); }
static void do_one_test (impl_t *impl, char *dst, char *src, const char *orig_src, size_t len) { size_t i, iters = INNER_LOOP_ITERS; timing_t start, stop, cur; /* This also clears the destination buffer set by the previous run. */ memcpy (src, orig_src, len); #ifdef TEST_BCOPY CALL (impl, src, dst, len); #else char *res; res = CALL (impl, dst, src, len); if (res != dst) { error (0, 0, "Wrong result in function %s %p %p", impl->name, res, dst); ret = 1; return; } #endif if (memcmp (dst, orig_src, len) != 0) { error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"", impl->name, dst, src); ret = 1; return; } TIMING_NOW (start); for (i = 0; i < iters; ++i) { #ifdef TEST_BCOPY CALL (impl, src, dst, len); #else CALL (impl, dst, src, len); #endif } TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); TIMING_PRINT_MEAN ((double) cur, (double) iters); }
static void do_one_test (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res) { size_t i, iters = INNER_LOOP_ITERS; timing_t start, stop, cur; TIMING_NOW (start); for (i = 0; i < iters; ++i) { CALL (impl, s, c); } TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); TIMING_PRINT_MEAN ((double) cur, (double) iters); }
static void do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result) { size_t i, iters = INNER_LOOP_ITERS; timing_t start, stop, cur; TIMING_NOW (start); for (i = 0; i < iters; ++i) { CALL (impl, s1, s2); } TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); TIMING_PRINT_MEAN ((double) cur, (double) iters); }
static void * benchmark_thread (void *arg) { struct thread_args *args = (struct thread_args *) arg; size_t iters; void *thread_set = args->working_set; timing_t start, stop; TIMING_NOW (start); iters = malloc_benchmark_loop (thread_set); TIMING_NOW (stop); TIMING_DIFF (args->elapsed, start, stop); args->iters = iters; return NULL; }
static void do_one_test (impl_t *impl, CHAR *dst, const CHAR *src, size_t len, size_t n) { size_t i, iters = INNER_LOOP_ITERS; timing_t start, stop, cur; if (CALL (impl, dst, src, n) != STRNCPY_RESULT (dst, len, n)) { error (0, 0, "Wrong result in function %s %p %p", impl->name, CALL (impl, dst, src, n), dst); ret = 1; return; } if (memcmp (dst, src, (len > n ? n : len) * sizeof (CHAR)) != 0) { error (0, 0, "Wrong result in function %s", impl->name); ret = 1; return; } if (n > len) { size_t i; for (i = len; i < n; ++i) if (dst [i] != '\0') { error (0, 0, "Wrong result in function %s", impl->name); ret = 1; return; } } TIMING_NOW (start); for (i = 0; i < iters; ++i) { CALL (impl, dst, src, n); } TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); TIMING_PRINT_MEAN ((double) cur, (double) iters); }
static void do_one_test (impl_t *impl, const void *haystack, size_t haystack_len, const void *needle, size_t needle_len, const void *expected) { size_t i, iters = INNER_LOOP_ITERS_SMALL; timing_t start, stop, cur; TIMING_NOW (start); for (i = 0; i < iters; ++i) { CALL (impl, haystack, haystack_len, needle, needle_len); } TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); TIMING_PRINT_MEAN ((double) cur, (double) iters); }
static void do_one_test (impl_t *impl, void *dst, const void *src, int c, size_t len, size_t n) { size_t i, iters = INNER_LOOP_ITERS; timing_t start, stop, cur; TIMING_NOW (start); for (i = 0; i < iters; ++i) { CALL (impl, dst, src, c, n); } TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); TIMING_PRINT_MEAN ((double) cur, (double) iters); }
static void do_one_test (json_ctx_t *json_ctx, impl_t *impl, char *dst, char *src, size_t len) { size_t i, iters = INNER_LOOP_ITERS; timing_t start, stop, cur; TIMING_NOW (start); for (i = 0; i < iters; ++i) { CALL (impl, dst, src, len); } TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); json_element_double (json_ctx, (double) cur / (double) iters); }
static void do_one_test (json_ctx_t *json_ctx, impl_t *impl, const CHAR *s1, const CHAR *s2, int exp_result) { size_t i, iters = INNER_LOOP_ITERS; timing_t start, stop, cur; TIMING_NOW (start); for (i = 0; i < iters; ++i) { CALL (impl, s1, s2); } TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); json_element_double (json_ctx, (double) cur / (double) iters); }
static void do_one_test (json_ctx_t *json_ctx, proto_t test_fn, volatile double *arr, size_t len, const char *testname) { size_t iters = 500; timing_t start, stop, cur; json_attr_object_begin (json_ctx, testname); TIMING_NOW (start); test_fn (arr, len, iters); TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); json_attr_double (json_ctx, "duration", cur); json_attr_double (json_ctx, "iterations", iters); json_attr_double (json_ctx, "mean", cur / iters); json_attr_object_end (json_ctx); }
static timing_t do_benchmark (size_t num_threads, size_t *iters) { timing_t elapsed = 0; if (num_threads == 1) { timing_t start, stop; void *working_set[WORKING_SET_SIZE]; memset (working_set, 0, sizeof (working_set)); TIMING_NOW (start); *iters = malloc_benchmark_loop (working_set); TIMING_NOW (stop); TIMING_DIFF (elapsed, start, stop); } else { struct thread_args args[num_threads]; void *working_set[num_threads][WORKING_SET_SIZE]; pthread_t threads[num_threads]; memset (working_set, 0, sizeof (working_set)); *iters = 0; for (size_t i = 0; i < num_threads; i++) { args[i].working_set = working_set[i]; pthread_create(&threads[i], NULL, benchmark_thread, &args[i]); } for (size_t i = 0; i < num_threads; i++) { pthread_join(threads[i], NULL); TIMING_ACCUM (elapsed, args[i].elapsed); *iters += args[i].iters; } } return elapsed; }
static void do_one_test (json_ctx_t *json_ctx, impl_t *impl, char *dst, char *src, size_t len) { size_t i = 0; timing_t start, stop, cur; char *dst_end = dst + MIN_PAGE_SIZE - len; char *src_end = src + MIN_PAGE_SIZE - len; TIMING_NOW (start); /* Copy the entire buffer backwards, LEN at a time. */ for (; src_end >= src && dst_end >= dst; src_end -= len, dst_end -= len, i++) CALL (impl, src_end, dst_end, len); TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); /* Get time taken per function call. */ json_element_double (json_ctx, (double) cur / i); }
static void do_one_test (impl_t *impl, char *dst, const char *src, size_t len) { size_t i, iters = 16; timing_t start, stop, cur; /* Must clear the destination buffer updated by the previous run. */ for (i = 0; i < len; i++) dst[i] = 0; if (CALL (impl, dst, src, len) != MEMCPY_RESULT (dst, len)) { error (0, 0, "Wrong result in function %s %p %p", impl->name, CALL (impl, dst, src, len), MEMCPY_RESULT (dst, len)); ret = 1; return; } if (memcmp (dst, src, len) != 0) { error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"", impl->name, dst, src); ret = 1; return; } TIMING_NOW (start); for (i = 0; i < iters; ++i) { CALL (impl, dst, src, len); } TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); TIMING_PRINT_MEAN ((double) cur, (double) iters); }
static void do_one_test (impl_t *impl, CHAR *s, int c __attribute ((unused)), size_t n) { size_t i, iters = INNER_LOOP_ITERS; timing_t start, stop, cur; CHAR tstbuf[n]; #ifdef TEST_BZERO simple_bzero (tstbuf, n); CALL (impl, s, n); if (memcmp (s, tstbuf, n) != 0) #else CHAR *res = CALL (impl, s, c, n); if (res != s || SIMPLE_MEMSET (tstbuf, c, n) != tstbuf || MEMCMP (s, tstbuf, n) != 0) #endif /* !TEST_BZERO */ { error (0, 0, "Wrong result in function %s", impl->name); ret = 1; return; } TIMING_NOW (start); for (i = 0; i < iters; ++i) { #ifdef TEST_BZERO CALL (impl, s, n); #else CALL (impl, s, c, n); #endif /* !TEST_BZERO */ } TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); TIMING_PRINT_MEAN ((double) cur, (double) iters); }
static void do_one_test (impl_t *impl, CHAR *s, int c __attribute ((unused)), size_t n) { size_t i, iters = 16; timing_t start, stop, cur; CHAR *tstbuf = malloc (n * sizeof (*s)); assert (tstbuf != NULL); /* Must clear the destination buffer updated by the previous run. */ for (i = 0; i < n; i++) s[i] = 0; CHAR *res = CALL (impl, s, c, n); if (res != s || SIMPLE_MEMSET (tstbuf, c, n) != tstbuf || MEMCMP (s, tstbuf, n) != 0) { error (0, 0, "Wrong result in function %s", impl->name); ret = 1; free (tstbuf); return; } TIMING_NOW (start); for (i = 0; i < iters; ++i) { CALL (impl, s, c, n); } TIMING_NOW (stop); TIMING_DIFF (cur, start, stop); TIMING_PRINT_MEAN ((double) cur, (double) iters); free (tstbuf); }
int main (int argc, char **argv) { unsigned long i, k; struct timespec runtime; timing_t start, end; startup(); memset (&runtime, 0, sizeof (runtime)); unsigned long iters, res; TIMING_INIT (res); iters = 1000 * res; for (int v = 0; v < NUM_VARIANTS; v++) { /* Run for approximately DURATION seconds. */ clock_gettime (CLOCK_MONOTONIC_RAW, &runtime); runtime.tv_sec += DURATION; double d_total_i = 0; timing_t total = 0, max = 0, min = 0x7fffffffffffffff; while (1) { for (i = 0; i < NUM_SAMPLES (v); i++) { uint64_t cur; TIMING_NOW (start); for (k = 0; k < iters; k++) BENCH_FUNC (v, i); TIMING_NOW (end); TIMING_DIFF (cur, start, end); if (cur > max) max = cur; if (cur < min) min = cur; TIMING_ACCUM (total, cur); d_total_i += iters; } struct timespec curtime; memset (&curtime, 0, sizeof (curtime)); clock_gettime (CLOCK_MONOTONIC_RAW, &curtime); if (TIMESPEC_AFTER (curtime, runtime)) goto done; } double d_total_s; double d_iters; done: d_total_s = total; d_iters = iters; TIMING_PRINT_STATS (VARIANT (v), d_total_s, d_iters, d_total_i, max, min); } return 0; }
int main (int argc, char **argv) { unsigned long i, k; struct timespec runtime; timing_t start, end; bool detailed = false; json_ctx_t json_ctx; if (argc == 2 && !strcmp (argv[1], "-d")) detailed = true; bench_start (); memset (&runtime, 0, sizeof (runtime)); unsigned long iters, res; #ifdef BENCH_INIT BENCH_INIT (); #endif TIMING_INIT (res); iters = 1000 * res; json_init (&json_ctx, 2, stdout); /* Begin function. */ json_attr_object_begin (&json_ctx, FUNCNAME); for (int v = 0; v < NUM_VARIANTS; v++) { /* Run for approximately DURATION seconds. */ clock_gettime (CLOCK_MONOTONIC_RAW, &runtime); runtime.tv_sec += DURATION; double d_total_i = 0; timing_t total = 0, max = 0, min = 0x7fffffffffffffff; int64_t c = 0; while (1) { for (i = 0; i < NUM_SAMPLES (v); i++) { uint64_t cur; TIMING_NOW (start); for (k = 0; k < iters; k++) BENCH_FUNC (v, i); TIMING_NOW (end); TIMING_DIFF (cur, start, end); if (cur > max) max = cur; if (cur < min) min = cur; TIMING_ACCUM (total, cur); /* Accumulate timings for the value. In the end we will divide by the total iterations. */ RESULT_ACCUM (cur, v, i, c * iters, (c + 1) * iters); d_total_i += iters; } c++; struct timespec curtime; memset (&curtime, 0, sizeof (curtime)); clock_gettime (CLOCK_MONOTONIC_RAW, &curtime); if (TIMESPEC_AFTER (curtime, runtime)) goto done; } double d_total_s; double d_iters; done: d_total_s = total; d_iters = iters; /* Begin variant. */ json_attr_object_begin (&json_ctx, VARIANT (v)); json_attr_double (&json_ctx, "duration", d_total_s); json_attr_double (&json_ctx, "iterations", d_total_i); json_attr_double (&json_ctx, "max", max / d_iters); json_attr_double (&json_ctx, "min", min / d_iters); json_attr_double (&json_ctx, "mean", d_total_s / d_total_i); if (detailed) { json_array_begin (&json_ctx, "timings"); for (int i = 0; i < NUM_SAMPLES (v); i++) json_element_double (&json_ctx, RESULT (v, i)); json_array_end (&json_ctx); } /* End variant. */ json_attr_object_end (&json_ctx); } /* End function. */ json_attr_object_end (&json_ctx); return 0; }