bench: fix nextN
[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 ns;
23 //static unsigned long long bytes;
24
25 #define SEC  1000000000ULL
26 #define MAXN 1000000000
27
28 static unsigned long long nsclock() {
29         struct timespec ts;
30         int r;
31
32 #ifdef _POSIX_CPUTIME
33         r = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
34 #else
35 #ifdef _POSIX_MONOTONIC_CLOCK
36         r = clock_gettime(CLOCK_MONOTONIC, &ts);
37 #else
38         r = clock_gettime(CLOCK_REALTIME, &ts);
39 #endif
40 #endif
41         if (r < 0) {
42                 fprintf(stderr, "bench: clock_gettime failed: %s\n", strerror(errno));
43                 return 0;
44         }
45         return ts.tv_sec*SEC + ts.tv_nsec;
46 }
47
48 void start_timer() {
49         if (!start)
50                 start = nsclock();
51 }
52
53 void stop_timer() {
54         if (start)
55                 ns += nsclock() - start;
56         start = 0;
57 }
58
59 void reset_timer() {
60         if (start)
61                 start = nsclock();
62         ns = 0;
63 }
64
65 static int nextN() {
66         unsigned long long n = ns/N;
67
68         if (n)
69                 n = SEC/n;
70         else
71                 n = SEC;
72         n += n/4;
73         if (n > N*100ULL)
74                 n = N*100ULL;
75         else if (n <= N)
76                 n = N+1;
77         if (n > MAXN)
78                 n = MAXN;
79         return n;
80 }
81
82 static void run(const char *name, void (*f)()) {
83         fprintf(stderr, "%s:", name);
84         for (N=1; ; N=nextN()) {
85                 reset_timer();
86                 start_timer();
87                 f();
88                 stop_timer();
89 //              fprintf(stderr, "%10d%12llu\n", N, ns);
90                 if (ns > SEC || N >= MAXN)
91                         break;
92                 if (N <= 0) {
93                         fprintf(stderr, "bench: fatal: N <= 0\n");
94                         return;
95                 }
96         }
97         if (ns/N > 100)
98                 fprintf(stderr, "%10d%10llu ns/op\n", N, ns/N);
99         else
100                 fprintf(stderr, "%10d%13.2f ns/op\n", N, (double)ns/N);
101 }
102
103 int main() {
104 #define B(t) run(#t, t);
105 #include "main.h"
106         return 0;
107 }