|
nsz |
a520c1 |
#define _POSIX_C_SOURCE 200809L
|
|
nsz |
a520c1 |
#include <stdlib.h>
|
|
nsz |
a520c1 |
#include <stdio.h>
|
|
nsz |
a520c1 |
#include <string.h>
|
|
nsz |
a520c1 |
#include <errno.h>
|
|
nsz |
a520c1 |
#include <time.h>
|
|
nsz |
a520c1 |
#include "test.h"
|
|
nsz |
a520c1 |
|
|
nsz |
a520c1 |
#define T(t)
|
|
nsz |
a520c1 |
#define B(t) void t();
|
|
nsz |
a520c1 |
#include "main.h"
|
|
nsz |
a520c1 |
#undef B
|
|
nsz |
a520c1 |
|
|
nsz |
a520c1 |
//static int verbose;
|
|
nsz |
a520c1 |
|
|
nsz |
a520c1 |
void error__(const char *n, int l, const char *s, ...) {
|
|
nsz |
a520c1 |
fprintf(stderr, "use error in tests only\n");
|
|
nsz |
a520c1 |
}
|
|
nsz |
a520c1 |
|
|
nsz |
a520c1 |
int N;
|
|
nsz |
a520c1 |
static unsigned long long start;
|
|
nsz |
a520c1 |
static unsigned long long ns;
|
|
nsz |
a520c1 |
//static unsigned long long bytes;
|
|
nsz |
a520c1 |
|
|
nsz |
a520c1 |
#define SEC 1000000000ULL
|
|
nsz |
a520c1 |
#define MAXN 1000000000
|
|
nsz |
a520c1 |
|
|
nsz |
a520c1 |
static unsigned long long nsclock() {
|
|
nsz |
a520c1 |
struct timespec ts;
|
|
nsz |
a520c1 |
int r;
|
|
nsz |
a520c1 |
|
|
nsz |
a520c1 |
#ifdef _POSIX_CPUTIME
|
|
nsz |
a520c1 |
r = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
|
|
nsz |
a520c1 |
#else
|
|
nsz |
a520c1 |
#ifdef _POSIX_MONOTONIC_CLOCK
|
|
nsz |
a520c1 |
r = clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
nsz |
a520c1 |
#else
|
|
nsz |
a520c1 |
r = clock_gettime(CLOCK_REALTIME, &ts);
|
|
nsz |
a520c1 |
#endif
|
|
nsz |
a520c1 |
#endif
|
|
nsz |
a520c1 |
if (r < 0) {
|
|
nsz |
a520c1 |
fprintf(stderr, "bench: clock_gettime failed: %s\n", strerror(errno));
|
|
nsz |
a520c1 |
return 0;
|
|
nsz |
a520c1 |
}
|
|
nsz |
a520c1 |
return ts.tv_sec*SEC + ts.tv_nsec;
|
|
nsz |
a520c1 |
}
|
|
nsz |
a520c1 |
|
|
nsz |
a520c1 |
void start_timer() {
|
|
nsz |
a520c1 |
if (!start)
|
|
nsz |
a520c1 |
start = nsclock();
|
|
nsz |
a520c1 |
}
|
|
nsz |
a520c1 |
|
|
nsz |
a520c1 |
void stop_timer() {
|
|
nsz |
a520c1 |
if (start)
|
|
nsz |
a520c1 |
ns += nsclock() - start;
|
|
nsz |
a520c1 |
start = 0;
|
|
nsz |
a520c1 |
}
|
|
nsz |
a520c1 |
|
|
nsz |
a520c1 |
void reset_timer() {
|
|
nsz |
a520c1 |
if (start)
|
|
nsz |
a520c1 |
start = nsclock();
|
|
nsz |
a520c1 |
ns = 0;
|
|
nsz |
a520c1 |
}
|
|
nsz |
a520c1 |
|
|
nsz |
a520c1 |
static int nextN() {
|
|
nsz |
a520c1 |
unsigned long long n = 2*SEC/(ns/N + 1);
|
|
nsz |
a520c1 |
if (n > N*100ULL)
|
|
nsz |
a520c1 |
n = N*100ULL;
|
|
nsz |
a520c1 |
else if (n <= N)
|
|
nsz |
a520c1 |
n = N+1;
|
|
nsz |
a520c1 |
if (n > MAXN)
|
|
nsz |
a520c1 |
n = MAXN;
|
|
nsz |
a520c1 |
return n;
|
|
nsz |
a520c1 |
}
|
|
nsz |
a520c1 |
|
|
nsz |
a520c1 |
static void run(const char *name, void (*f)()) {
|
|
nsz |
a520c1 |
fprintf(stderr, "%s:", name);
|
|
nsz |
a520c1 |
for (N=1; ; N=nextN()) {
|
|
nsz |
a520c1 |
reset_timer();
|
|
nsz |
a520c1 |
start_timer();
|
|
nsz |
a520c1 |
f();
|
|
nsz |
a520c1 |
stop_timer();
|
|
nsz |
a520c1 |
// fprintf(stderr, "%10d%12llu\n", N, ns);
|
|
nsz |
a520c1 |
if (ns > SEC || N >= MAXN)
|
|
nsz |
a520c1 |
break;
|
|
nsz |
a520c1 |
if (N <= 0) {
|
|
nsz |
a520c1 |
fprintf(stderr, "bench: fatal: N <= 0\n");
|
|
nsz |
a520c1 |
return;
|
|
nsz |
a520c1 |
}
|
|
nsz |
a520c1 |
}
|
|
nsz |
a520c1 |
if (ns/N > 100)
|
|
nsz |
a520c1 |
fprintf(stderr, "%10d%10llu ns/op\n", N, ns/N);
|
|
nsz |
a520c1 |
else
|
|
nsz |
a520c1 |
fprintf(stderr, "%10d%13.2f ns/op\n", N, (double)ns/N);
|
|
nsz |
a520c1 |
}
|
|
nsz |
a520c1 |
|
|
nsz |
a520c1 |
int main() {
|
|
nsz |
a520c1 |
#define B(t) run(#t, t);
|
|
nsz |
a520c1 |
#include "main.h"
|
|
nsz |
a520c1 |
return 0;
|
|
nsz |
a520c1 |
}
|