ee6daa114568bd95e853123f36defcce761834e7
[libc-test] / common / bench.c
1 #define _POSIX_C_SOURCE 200809L
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <errno.h>
6 #include <time.h>
7 #include "test.h"
8
9 #define T(t)
10 #define B(t) void t();
11 #include "main.h"
12 #undef B
13
14 //static int verbose;
15
16 void error__(const char *n, int l, const char *s, ...) {
17         fprintf(stderr, "use error in tests only\n");
18 }
19
20 int N;
21 static unsigned long long start;
22 static unsigned long long dt;
23 //static unsigned long long bytes;
24
25 #define SEC  1000000000ULL
26 #define MAXN 1000000000
27
28 static unsigned long long tic() {
29         struct timespec ts;
30
31         if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) {
32                 fprintf(stderr, "bench: clock_gettime failed: %s\n", strerror(errno));
33                 return 0;
34         }
35         return ts.tv_sec*SEC + ts.tv_nsec;
36 }
37
38 void start_timer() {
39         if (!start)
40                 start = tic();
41 }
42
43 void stop_timer() {
44         if (start)
45                 dt += tic() - start;
46         start = 0;
47 }
48
49 void reset_timer() {
50         if (start)
51                 start = tic();
52         dt = 0;
53 }
54
55 static int nextN() {
56         unsigned long long n = dt/N;
57
58         if (n)
59                 n = SEC/n;
60         else
61                 n = SEC;
62         n += n/4;
63         if (n > N*100ULL)
64                 n = N*100ULL;
65         else if (n <= N)
66                 n = N+1;
67         if (n > MAXN)
68                 n = MAXN;
69         return n;
70 }
71
72 static void run(const char *name, void (*f)()) {
73         fprintf(stderr, "%s:", name);
74         for (N=1; ; N=nextN()) {
75                 reset_timer();
76                 start_timer();
77                 f();
78                 stop_timer();
79 //              fprintf(stderr, "%10d%12llu\n", N, ns);
80                 if (dt >= SEC || N >= MAXN)
81                         break;
82                 if (N <= 0) {
83                         fprintf(stderr, "bench: fatal: N <= 0\n");
84                         return;
85                 }
86         }
87         if (dt/N > 100)
88                 fprintf(stderr, "%10d%10llu ns/op\n", N, dt/N);
89         else
90                 fprintf(stderr, "%10d%13.2f ns/op\n", N, (double)dt/N);
91 }
92
93 int main() {
94 #define B(t) run(#t, t);
95 #include "main.h"
96         return 0;
97 }