-
-
Save benwaffle/9fee8ef3eb724e2ea8ed to your computer and use it in GitHub Desktop.
benchmark flip() and flop()
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _PROB_BENCHMARK_H_ | |
#define _PROB_BENCHMARK_H_ | |
#define _GNU_SOURCE | |
#include <stdio.h> | |
#include <time.h> | |
#define KNRM "\x1B[0m" // normal console color | |
#define KRED "\x1B[31m" | |
#define KGRN "\x1B[32m" | |
#define KYEL "\x1B[33m" | |
#define KBLU "\x1B[34m" | |
#define KMAG "\x1B[35m" | |
#define KCYN "\x1B[36m" | |
#define KWHT "\x1B[37m" | |
#define KRST "\033[0m" // resets to previous console color | |
#ifndef abs | |
# define abs(n) (n) < 0 ? -(n) : (n) | |
#endif | |
#define BENCHMARK_TIMES_FEW 1000u | |
#define BENCHMARK_TIMES_NORM BENCHMARK_TIMES_FEW*1000u | |
#define BENCHMARK_TIMES_MANY BENCHMARK_TIMES_NORM*10u | |
/* | |
* Use: run benchmark_flip() with just the function pointer flip as your | |
* argument. | |
*/ | |
#define benchmark_flip(func,times) \ | |
do {\ | |
unsigned n;\ | |
double avg, err;\ | |
struct timespec start, end;\ | |
printf(KBLU"benchmark:"KRST" running flip() %u times\n", times);\ | |
clock_gettime(CLOCK_MONOTONIC, &start);\ | |
for (n=0, avg=0; n<times; avg /= ++n)\ | |
avg = n*avg + func();\ | |
clock_gettime(CLOCK_MONOTONIC, &end);\ | |
err = abs(100*(avg-0.5)/0.5);\ | |
printf("\tE(X) = %lf (expected: %lf, error: %s%f%%"KRST") (time: %lf sec)\n", \ | |
avg,\ | |
0.5,\ | |
err > 5 ? (err > 50 ? KRED : KYEL) : KGRN,\ | |
abs(100*(avg-0.5)/0.5),\ | |
(end.tv_nsec - start.tv_nsec + (1000000000*(end.tv_sec - start.tv_sec))) / 1000000000.0);\ | |
} while (0) | |
/* Use: test low, mid, high benchmarks on function */ | |
#define benchmark_flip_test(func)\ | |
do {\ | |
benchmark_flip(func,BENCHMARK_TIMES_FEW);\ | |
benchmark_flip(func,BENCHMARK_TIMES_NORM);\ | |
benchmark_flip(func,BENCHMARK_TIMES_MANY);\ | |
} while (0) | |
/* | |
* Use: run benchmark_flop() with flop as func, and (a,b) as (m,n). | |
*/ | |
#define benchmark_flop(func,a,b,times) \ | |
do {\ | |
unsigned n;\ | |
double avg, err;\ | |
double e = (double)a/b;\ | |
struct timespec start, end;\ | |
printf(KBLU"benchmark:"KRST" running flop(%d,%d) (p=%lf) %u times\n",\ | |
a, b, e, times);\ | |
clock_gettime(CLOCK_MONOTONIC, &start);\ | |
for (n=0, avg; n<times; avg /= ++n)\ | |
avg = n*avg + func(a,b);\ | |
clock_gettime(CLOCK_MONOTONIC, &end);\ | |
err = e == 0 ? 0 : abs(100*(avg-e)/e);\ | |
printf("\tE(X) = %lf (expected: %lf, error: %s%f%%"KRST") (time: %lf sec)\n", \ | |
avg,\ | |
e,\ | |
err > 5 ? (err > 50 ? KRED : KYEL) : KGRN,\ | |
err,\ | |
(end.tv_nsec - start.tv_nsec + (1000000000*(end.tv_sec - start.tv_sec))) / 1000000000.0);\ | |
} while (0) | |
/* Use: test low, mid, high benchmarks on function */ | |
#define benchmark_flop_test(func,a,b)\ | |
do {\ | |
benchmark_flop(func,a,b,BENCHMARK_TIMES_FEW);\ | |
benchmark_flop(func,a,b,BENCHMARK_TIMES_NORM);\ | |
benchmark_flop(func,a,b,BENCHMARK_TIMES_MANY);\ | |
} while (0) | |
#define benchmark_flop_test_all_p(func)\ | |
do {\ | |
int num;\ | |
printf(KBLU"meta benchmark:"\ | |
KRST" testing flop() for 100 p in [0,1]\n");\ | |
for (num=0; num<100; ++num)\ | |
benchmark_flop(func,num,100,BENCHMARK_TIMES_FEW);\ | |
} while (0) | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment