summaryrefslogtreecommitdiff
path: root/lib/libc_r/BENCH/bench.h
blob: 6e8eb581cb840af236c6e5a407cd47ccdced98e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

/* The default number of cycles per test */
#define BENCH_LOOPS	(100000)

#include <sys/time.h>

typedef struct  {
	int i;				/* loop counter */
	int n;				/* loop maximum */
	int divisor;			/* operations per cycle */
	struct timeval start;		/* start time */
	struct timeval end;		/* end time */
	char *name;			/* benchmark title */
	char *doc;			/* benchmark description */
	char *units;			/* measurement units information */
} bench_t;

#define bench_now(tvp) \
	gettimeofday((tvp),0)

/*
 * Repeat the body of the loop 'max' times, with a few extra 'warm up'
 * cycles to negate cache effects.
 */
#define bench_amortize(b, max) 						\
	for ((b)->i = -64,						\
	     (b)->n = (max);						\
	     (b)->i < (b)->n;						\
	     (b)->i ++,							\
	     ((b)->i == 0 ? bench_now(&(b)->start) :			\
	      ((b)->i == (b)->n ? bench_now(&(b)->end)			\
		:0))\
	)

#define bench_init(b, nm, dc, un) do {					\
	(b)->name = (nm);						\
	(b)->doc = (dc);						\
	(b)->units = (un);						\
	timerclear(&(b)->start);					\
	timerclear(&(b)->end);						\
	(b)->n = (b)->i = 0;						\
	(b)->divisor = 1;						\
} while (0)
	
#define bench_header(b)							\
	printf("----------------------------------------------------\n" \
	       "Name:\t%s\nDesc:%s\n",	(b)->name, (b)->doc)

#define bench_report(b) do {						\
	bench_t overhead;						\
	struct timeval oh_elapsed;					\
	struct timeval elapsed;						\
	struct timeval normal;						\
	double average;							\
									\
	/* compute the loop overhead */					\
	bench_amortize(&overhead, (b)->n) { /* nothing */ }		\
									\
	/* compute the test time */					\
	timersub(&(b)->end, &(b)->start, &elapsed);			\
	timersub(&overhead.end, &overhead.start, &oh_elapsed);		\
	timersub(&elapsed, &oh_elapsed, &normal);			\
									\
	average = ((double)normal.tv_sec * 1000000.0 +			\
	    normal.tv_usec) / (double)((b)->divisor) / 			\
	    (double)((b)->n);						\
									\
	printf("Time: %f usec %s\n", average, (b)->units);		\
} while (0)