xref: /plan9/sys/src/cmd/ki/stats.c (revision f2baf03bd6df5a6aaf286817c52b37d25196392a)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <bio.h>
4bd389b36SDavid du Colombier #include <mach.h>
53e12c5d1SDavid du Colombier #define Extern extern
63e12c5d1SDavid du Colombier #include "sparc.h"
73e12c5d1SDavid du Colombier 
8*f2baf03bSDavid du Colombier #define prof profki
93e12c5d1SDavid du Colombier #define Percent(num, max)	(((num)*100)/(max))
103e12c5d1SDavid du Colombier 
113e12c5d1SDavid du Colombier extern Inst op0[], op2[], op3[];
123e12c5d1SDavid du Colombier Inst *tables[] = { op0, op2, op3, 0 };
133e12c5d1SDavid du Colombier 
143e12c5d1SDavid du Colombier void
isum(void)153e12c5d1SDavid du Colombier isum(void)
163e12c5d1SDavid du Colombier {
173e12c5d1SDavid du Colombier 	Inst *i;
183e12c5d1SDavid du Colombier 	int pct, j;
193e12c5d1SDavid du Colombier 	int total, loads, stores, arith, branch;
203e12c5d1SDavid du Colombier 	int useddelay, taken, sparcreg, syscall, realarith;
213e12c5d1SDavid du Colombier 
223e12c5d1SDavid du Colombier 	total = 0;
233e12c5d1SDavid du Colombier 	loads = 0;
243e12c5d1SDavid du Colombier 	stores = 0;
253e12c5d1SDavid du Colombier 	arith = 0;
263e12c5d1SDavid du Colombier 	branch = 0;
273e12c5d1SDavid du Colombier 	useddelay = 0;
283e12c5d1SDavid du Colombier 	taken = 0;
293e12c5d1SDavid du Colombier 	sparcreg = 0;
303e12c5d1SDavid du Colombier 	syscall = 0;
313e12c5d1SDavid du Colombier 	realarith = 0;
323e12c5d1SDavid du Colombier 
333e12c5d1SDavid du Colombier 	/* Compute the total so we can have percentages */
343e12c5d1SDavid du Colombier 	for(j = 0; tables[j]; j++)
353e12c5d1SDavid du Colombier 		for(i = tables[j]; i->func; i++)
363e12c5d1SDavid du Colombier 			if(i->name && i->count)
373e12c5d1SDavid du Colombier 				total += i->count;
383e12c5d1SDavid du Colombier 
393e12c5d1SDavid du Colombier 	Bprint(bioout, "\nInstruction summary.\n\n");
403e12c5d1SDavid du Colombier 
413e12c5d1SDavid du Colombier 	for(j = 0; tables[j]; j++) {
423e12c5d1SDavid du Colombier 		for(i =tables[j]; i->func; i++) {
433e12c5d1SDavid du Colombier 			if(i->name) {
443e12c5d1SDavid du Colombier 				if(i->count == 0)
453e12c5d1SDavid du Colombier 					continue;
463e12c5d1SDavid du Colombier 				pct = Percent(i->count, total);
473e12c5d1SDavid du Colombier 				if(pct != 0)
487dd7cddfSDavid du Colombier 					Bprint(bioout, "%-8ud %3d%% %s\n",
493e12c5d1SDavid du Colombier 					i->count, Percent(i->count, total), i->name);
503e12c5d1SDavid du Colombier 				else
517dd7cddfSDavid du Colombier 					Bprint(bioout, "%-8ud      %s\n",
523e12c5d1SDavid du Colombier 					i->count, i->name);
533e12c5d1SDavid du Colombier 
543e12c5d1SDavid du Colombier 				switch(i->type) {
553e12c5d1SDavid du Colombier 				default:
563e12c5d1SDavid du Colombier 					fatal(0, "isum bad stype %d\n", i->type);
573e12c5d1SDavid du Colombier 				case Iload:
583e12c5d1SDavid du Colombier 					loads += i->count;
593e12c5d1SDavid du Colombier 					break;
603e12c5d1SDavid du Colombier 				case Istore:
613e12c5d1SDavid du Colombier 					stores += i->count;
623e12c5d1SDavid du Colombier 					break;
633e12c5d1SDavid du Colombier 				case Iarith:
643e12c5d1SDavid du Colombier 					arith += i->count;
653e12c5d1SDavid du Colombier 					break;
663e12c5d1SDavid du Colombier 				case Ibranch:
673e12c5d1SDavid du Colombier 					branch += i->count;
683e12c5d1SDavid du Colombier 					taken += i->taken;
693e12c5d1SDavid du Colombier 					useddelay += i->useddelay;
703e12c5d1SDavid du Colombier 					break;
713e12c5d1SDavid du Colombier 				case Ireg:
723e12c5d1SDavid du Colombier 					sparcreg += i->count;
733e12c5d1SDavid du Colombier 					break;
743e12c5d1SDavid du Colombier 				case Isyscall:
753e12c5d1SDavid du Colombier 					syscall += i->count;
763e12c5d1SDavid du Colombier 					break;
773e12c5d1SDavid du Colombier 				case Ifloat:
783e12c5d1SDavid du Colombier 					realarith += i->count;
793e12c5d1SDavid du Colombier 					break;
803e12c5d1SDavid du Colombier 				case Inop:
813e12c5d1SDavid du Colombier 					arith += i->count;
823e12c5d1SDavid du Colombier 					i->count -= nopcount;
833e12c5d1SDavid du Colombier 					break;
843e12c5d1SDavid du Colombier 				}
853e12c5d1SDavid du Colombier 			}
863e12c5d1SDavid du Colombier 		}
873e12c5d1SDavid du Colombier 	}
883e12c5d1SDavid du Colombier 
893e12c5d1SDavid du Colombier 	total += anulled;
907dd7cddfSDavid du Colombier 	Bprint(bioout, "\n%-8ud      Memory cycles\n", loads+stores+total);
913e12c5d1SDavid du Colombier 
927dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Instruction cycles\n",
933e12c5d1SDavid du Colombier 				total, Percent(total, loads+stores+total));
947dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8lud %3ld%% Annulled branch cycles\n",
95bd389b36SDavid du Colombier 				anulled, Percent(anulled, total));
963e12c5d1SDavid du Colombier 
977dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Data cycles\n\n",
983e12c5d1SDavid du Colombier 				loads+stores, Percent(loads+stores, loads+stores+total));
993e12c5d1SDavid du Colombier 
1007dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Stores\n", stores, Percent(stores, total));
1013e12c5d1SDavid du Colombier 
1027dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Loads\n", loads, Percent(loads, total));
1033e12c5d1SDavid du Colombier 
1047dd7cddfSDavid du Colombier 	Bprint(bioout, "   %-8ud Store stall\n", stores*2);
1053e12c5d1SDavid du Colombier 
1063e12c5d1SDavid du Colombier 	Bprint(bioout, "   %-8lud Load stall\n", loadlock);
1073e12c5d1SDavid du Colombier 
1087dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Arithmetic\n", arith, Percent(arith, total));
1093e12c5d1SDavid du Colombier 
1107dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Floating point\n",
1113e12c5d1SDavid du Colombier 					realarith, Percent(realarith, total));
1123e12c5d1SDavid du Colombier 
1137dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Sparc special register load/stores\n",
1143e12c5d1SDavid du Colombier 					sparcreg, Percent(sparcreg, total));
1153e12c5d1SDavid du Colombier 
1167dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% System calls\n", syscall, Percent(syscall, total));
1173e12c5d1SDavid du Colombier 
1187dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Branches\n", branch, Percent(branch, total));
1193e12c5d1SDavid du Colombier 
1207dd7cddfSDavid du Colombier 	Bprint(bioout, "   %-8ud %3d%% Branches taken\n",
1213e12c5d1SDavid du Colombier 					taken, Percent(taken, branch));
1223e12c5d1SDavid du Colombier 
1237dd7cddfSDavid du Colombier 	Bprint(bioout, "   %-8ud %3d%% Delay slots\n",
1243e12c5d1SDavid du Colombier 					useddelay, Percent(useddelay, branch));
1253e12c5d1SDavid du Colombier 
1267dd7cddfSDavid du Colombier 	Bprint(bioout, "   %-8ud %3d%% Unused delay slots\n",
1273e12c5d1SDavid du Colombier 					nopcount, Percent(nopcount, branch));
1283e12c5d1SDavid du Colombier 
1297dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Program total delay slots\n",
1303e12c5d1SDavid du Colombier 					nopcount, Percent(nopcount, total));
1313e12c5d1SDavid du Colombier }
1323e12c5d1SDavid du Colombier 
1333e12c5d1SDavid du Colombier char *stype[] = { "Stack", "Text", "Data", "Bss" };
1343e12c5d1SDavid du Colombier 
1353e12c5d1SDavid du Colombier void
segsum(void)1363e12c5d1SDavid du Colombier segsum(void)
1373e12c5d1SDavid du Colombier {
1383e12c5d1SDavid du Colombier 	Segment *s;
1393e12c5d1SDavid du Colombier 	int i;
1403e12c5d1SDavid du Colombier 
1413e12c5d1SDavid du Colombier 	Bprint(bioout, "\n\nMemory Summary\n\n");
1423e12c5d1SDavid du Colombier 	Bprint(bioout, "      Base     End      Resident References\n");
1433e12c5d1SDavid du Colombier 	for(i = 0; i < Nseg; i++) {
1443e12c5d1SDavid du Colombier 		s = &memory.seg[i];
1453e12c5d1SDavid du Colombier 		Bprint(bioout, "%-5s %.8lux %.8lux %-8d %-8d\n",
1463e12c5d1SDavid du Colombier 				stype[i], s->base, s->end, s->rss*BY2PG, s->refs);
1473e12c5d1SDavid du Colombier 	}
1483e12c5d1SDavid du Colombier }
1493e12c5d1SDavid du Colombier 
1503e12c5d1SDavid du Colombier typedef struct Prof Prof;
1513e12c5d1SDavid du Colombier struct Prof
1523e12c5d1SDavid du Colombier {
1533e12c5d1SDavid du Colombier 	Symbol	s;
1543e12c5d1SDavid du Colombier 	long	count;
1553e12c5d1SDavid du Colombier };
1563e12c5d1SDavid du Colombier Prof	prof[5000];
1573e12c5d1SDavid du Colombier 
1583e12c5d1SDavid du Colombier int
profcmp(void * va,void * vb)1597dd7cddfSDavid du Colombier profcmp(void *va, void *vb)
1603e12c5d1SDavid du Colombier {
1617dd7cddfSDavid du Colombier 	Prof *a, *b;
1627dd7cddfSDavid du Colombier 
1637dd7cddfSDavid du Colombier 	a = va;
1647dd7cddfSDavid du Colombier 	b = vb;
1653e12c5d1SDavid du Colombier 	return b->count - a->count;
1663e12c5d1SDavid du Colombier }
1673e12c5d1SDavid du Colombier 
1683e12c5d1SDavid du Colombier void
iprofile(void)1693e12c5d1SDavid du Colombier iprofile(void)
1703e12c5d1SDavid du Colombier {
1713e12c5d1SDavid du Colombier 	Prof *p, *n;
1723e12c5d1SDavid du Colombier 	int i, b, e;
173bd389b36SDavid du Colombier 	ulong total;
174bd389b36SDavid du Colombier 	extern ulong textbase;
1753e12c5d1SDavid du Colombier 
1763e12c5d1SDavid du Colombier 	i = 0;
1773e12c5d1SDavid du Colombier 	p = prof;
1783e12c5d1SDavid du Colombier 	if(textsym(&p->s, i) == 0)
1793e12c5d1SDavid du Colombier 		return;
1803e12c5d1SDavid du Colombier 	i++;
1813e12c5d1SDavid du Colombier 	for(;;) {
1823e12c5d1SDavid du Colombier 		n = p+1;
1833e12c5d1SDavid du Colombier 		if(textsym(&n->s, i) == 0)
1843e12c5d1SDavid du Colombier 			break;
185bd389b36SDavid du Colombier 		b = (p->s.value-textbase)/PROFGRAN;
186bd389b36SDavid du Colombier 		e = (n->s.value-textbase)/PROFGRAN;
1873e12c5d1SDavid du Colombier 		while(b < e)
1883e12c5d1SDavid du Colombier 			p->count += iprof[b++];
1893e12c5d1SDavid du Colombier 		i++;
1903e12c5d1SDavid du Colombier 		p = n;
1913e12c5d1SDavid du Colombier 	}
1923e12c5d1SDavid du Colombier 
1933e12c5d1SDavid du Colombier 	qsort(prof, i, sizeof(Prof), profcmp);
1943e12c5d1SDavid du Colombier 
1953e12c5d1SDavid du Colombier 	total = 0;
1963e12c5d1SDavid du Colombier 	for(b = 0; b < i; b++)
1973e12c5d1SDavid du Colombier 		total += prof[b].count;
1983e12c5d1SDavid du Colombier 
1993e12c5d1SDavid du Colombier 	Bprint(bioout, "  cycles     %% symbol          file\n");
2003e12c5d1SDavid du Colombier 	for(b = 0; b < i; b++) {
2013e12c5d1SDavid du Colombier 		if(prof[b].count == 0)
2023e12c5d1SDavid du Colombier 			continue;
2033e12c5d1SDavid du Colombier 
2047dd7cddfSDavid du Colombier 		Bprint(bioout, "%8ld %3ld.%ld %-15s ",
2053e12c5d1SDavid du Colombier 			prof[b].count,
2063e12c5d1SDavid du Colombier 			100*prof[b].count/total,
2073e12c5d1SDavid du Colombier 			(1000*prof[b].count/total)%10,
2083e12c5d1SDavid du Colombier 			prof[b].s.name);
2093e12c5d1SDavid du Colombier 
2103e12c5d1SDavid du Colombier 		printsource(prof[b].s.value);
2113e12c5d1SDavid du Colombier 		Bputc(bioout, '\n');
2123e12c5d1SDavid du Colombier 	}
2133e12c5d1SDavid du Colombier 	memset(prof, 0, sizeof(Prof)*i);
2143e12c5d1SDavid du Colombier }
215