286 lines · 4.7 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <tos.h>#include "b.h" #define MAX(a,b) ((a)>(b)?(a):(b)) enum {	OneS = 1000000000ULL,	Btime = OneS/10ULL,	Bstepmin = 100,}; static uvlong adj; #if defined(__386__) || defined(__amd64__)typedef struct Res {	ulong ax, bx, cx, dx;}Res;Res cpuid(ulong ax, ulong cx);void _tendp(uvlong *c);#endif void _tend(uvlong *c);void (*tend)(uvlong *c); uvlongcycles2ns(uvlong x){	uvlong div; 	/* this is ugly */	for(div = OneS; x < 0x1999999999999999ULL && div > 1 ; div /= 10ULL, x *= 10ULL); 	return x / (_tos->cyclefreq / div);} static intσfmt(Fmt *f){	B *b; 	b = va_arg(f->args, B*); 	return fmtprint(f, "%ulld", OneS/(b->tot.ns/b->ic));} static intτfmt(Fmt *f){	Cns c; 	c = va_arg(f->args, Cns); 	return fmtprint(f,	"%ulld", c.ns);} B *benchinit(B *b, char *name){	int i; 	fmtinstall(L'σ', σfmt);	fmtinstall(L'τ', τfmt); 	if(tend == nil){		tend = _tend;#if defined(__386__) || defined(__amd64__)		Res r;		r = cpuid(0x80000001, 2);		if(r.dx & (1<<27))			tend = _tendp;#endif	} 	memset(b, 0, sizeof(*b));	b->name = name;	b->n = b->nc = Bstepmin;	b->min.c--;	b->c = mallocz(b->nc * sizeof(*b->c), 1); 	if(adj == 0){		uvlong v;		for(i = 0, v = 0; i < 100; i++){			uvlong s, e;			tstart(&s);			tend(&e);			v += e - s;		}		adj = v / i;	} 	return b;} B *benchadd(Bgr *gr, char *name){	B **gb, *b; 	if((gb = realloc(gr->b, (gr->nb+1)*sizeof(b))) == nil)		return nil;	gr->b = gb;	if((b = malloc(sizeof(*b)+strlen(name)+1)) == nil)		return nil;	gr->b[gr->nb++] = b; 	return benchinit(b, strcpy((char*)(b+1), name));} Bgr *benchinitgr(Bgr *gr, char *name){	gr->name = name;	gr->b = nil;	gr->nb = 0; 	return gr;} voidbenchprintgr(Bgr *gr, int fd){	fprint(fd, "%s\n", gr->name);	benchprint(gr->b, gr->nb, fd);} voidbenchfreegr(Bgr *gr){	int i; 	for(i = 0; i < gr->nb; i++)		free(gr->b[i]);} voidbseparator(int fd){	fprint(fd, "\n");} static intccmp(void *a, void *b){	u32int *x, *y; 	x = a;	y = b; 	return *x < *y ? -1 : (*x > *y ? 1 : 0);} static voidbenchcalc(B *b){	uvlong m;	int i, n; 	qsort(b->c, b->ic, sizeof(*b->c), ccmp); 	if(b->ic & 1)		m = b->c[b->ic/2];	else		m = (b->c[b->ic/2-1] + b->c[b->ic/2])/2;	b->med.c = m;	b->med.ns = cycles2ns(b->med.c);	b->avg.c = b->tot.c / b->step;	b->avg.ns = cycles2ns(b->avg.c);	b->min.c = b->c[0];	b->min.ns = cycles2ns(b->min.c);	b->max.c = b->c[b->ic-1];	b->max.ns = cycles2ns(b->max.c);	for(i = 1; i < 100; i++){		n = MAX(0, b->ic*i/100 - 1);		b->p[i].ns = cycles2ns(b->c[n]);	}} voidbenchstep(B *b){	uvlong c; 	if(b->n < 1 || b->tout <= b->tin)		return; 	if(b->step == 0)		b->t0 = b->tin;	b->step++;	b->n--; 	if(b->tout - b->tin < adj) /* sometimes this happens */		adj = b->tout - b->tin;	c = b->tout - b->tin - adj;	if(b->ic >= b->nc){		b->nc *= 2;		b->c = realloc(b->c, b->nc * sizeof(*b->c));		memset(b->c+b->ic, 0, sizeof(*b->c)*(b->nc - b->ic));	}	b->c[b->ic++] = c; 	b->tot.c += c;	b->tot.ns = cycles2ns(b->tot.c); 	if(b->n == 0){		uvlong nsall = cycles2ns(b->tout - b->t0);		if(nsall < Btime)			b->n = (Btime - nsall) / (nsall / b->step);		if(b->n == 0){			benchcalc(b);			free(b->c);		}	}} voidbenchprint(B **b, int nb, int fd){	static char *header[] = {"   ", "op/s", "98%", "96%", "75%", "med", "avg", "min", "max"};	static int w[] = {16, 8, 8, 8, 8, 8, 8, 8, 8};	static int off[] = {		0,		0,		offsetof(B, p[99]),		offsetof(B, p[95]),		offsetof(B, p[75]),		offsetof(B, med),		offsetof(B, avg),		offsetof(B, min),		offsetof(B, max),	};	char t[64], *s, *p;	int i, j, n, x; 	for(i = 0; i < nb; i++){		w[0] = MAX(w[0], snprint(t, sizeof(t), "%s  ", b[i]->name ? b[i]->name : ""));		w[1] = MAX(w[1], snprint(t, sizeof(t), "%σ  ", b[i]));		for(j = 2; j < nelem(header); j++)			w[j] = MAX(w[j], snprint(t, sizeof(t), "%τ  ", *(Cns*)((char*)b[i] + off[j])));	} 	for(j = n = 0; j < nelem(header); j++)		n += w[j];	s = malloc(n+1);	memset(s, ' ', n);	for(j = 0, p = s; j < nelem(header); p += w[j++]){		x = snprint(t, sizeof(t), "%s  ", header[j]);		memmove(p+w[j]-x, t, x);	}	*p = 0;	fprint(fd, "%s\n", s); 	for(i = 0; i < nb; i++){		memset(s, ' ', n);		p = s;		p[sprint(p, "%s  ", b[i]->name)] = ' ';		p += w[0];		x = snprint(t, sizeof(t), "%σ  ", b[i]);		memmove(p+w[1]-x, t, x);		p += w[1];		for(j = 2; j < nelem(header); p += w[j], j++){			x = snprint(t, sizeof(t), "%τ  ", *(Cns*)((char*)b[i] + off[j]));			memmove(p+w[j]-x, t, x);		}		*p = 0;		fprint(fd, "%s\n", s);	}} intbenchwire(int cpu){	char t[64];	int r, f; 	r = -1;	snprint(t, sizeof(t), "/proc/%d/ctl", getpid());	if((f = open(t, OWRITE)) >= 0){		if(fprint(f, "wired %d\n", cpu) >= 8)			r = 0;		close(f);	} 	return r;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t