xref: /plan9/sys/src/cmd/5i/stats.c (revision e288d156a88911460b465926f0fb6de139f6d766)
17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <bio.h>
47dd7cddfSDavid du Colombier #include <mach.h>
57dd7cddfSDavid du Colombier #include "arm.h"
67dd7cddfSDavid du Colombier 
780ee5cbfSDavid du Colombier #define Percent(num, max)	((max)?((num)*100)/(max):0)
8*e288d156SDavid du Colombier #define prof prof5i
97dd7cddfSDavid du Colombier 
107dd7cddfSDavid du Colombier extern	Inst	itab[];
117dd7cddfSDavid du Colombier Inst *tables[] = { itab, 0 };
127dd7cddfSDavid du Colombier 
137dd7cddfSDavid du Colombier void
isum(void)147dd7cddfSDavid du Colombier isum(void)
157dd7cddfSDavid du Colombier {
167dd7cddfSDavid du Colombier 	Inst *i;
1780ee5cbfSDavid du Colombier 	int total, mems, arith, branch;
1880ee5cbfSDavid du Colombier 	int useddelay, taken, syscall;
197dd7cddfSDavid du Colombier 	int pct, j;
207dd7cddfSDavid du Colombier 
217dd7cddfSDavid du Colombier 	total = 0;
2280ee5cbfSDavid du Colombier 	mems = 0;
237dd7cddfSDavid du Colombier 	arith = 0;
247dd7cddfSDavid du Colombier 	branch = 0;
257dd7cddfSDavid du Colombier 	useddelay = 0;
267dd7cddfSDavid du Colombier 	taken = 0;
277dd7cddfSDavid du Colombier 	syscall = 0;
287dd7cddfSDavid du Colombier 
297dd7cddfSDavid du Colombier 	/* Compute the total so we can have percentages */
307dd7cddfSDavid du Colombier 	for(i = itab; i->func; i++)
317dd7cddfSDavid du Colombier 		if(i->name && i->count)
327dd7cddfSDavid du Colombier 			total += i->count;
337dd7cddfSDavid du Colombier 
347dd7cddfSDavid du Colombier 	Bprint(bioout, "\nInstruction summary.\n\n");
357dd7cddfSDavid du Colombier 
367dd7cddfSDavid du Colombier 	for(j = 0; tables[j]; j++) {
377dd7cddfSDavid du Colombier 		for(i = tables[j]; i->func; i++) {
387dd7cddfSDavid du Colombier 			if(i->name) {
397dd7cddfSDavid du Colombier 				/* This is gross */
407dd7cddfSDavid du Colombier 				if(i->count == 0)
417dd7cddfSDavid du Colombier 					continue;
427dd7cddfSDavid du Colombier 				pct = Percent(i->count, total);
437dd7cddfSDavid du Colombier 				if(pct != 0)
447dd7cddfSDavid du Colombier 					Bprint(bioout, "%-8ud %3d%% %s\n",
457dd7cddfSDavid du Colombier 						i->count, Percent(i->count,
467dd7cddfSDavid du Colombier 						total), i->name);
477dd7cddfSDavid du Colombier 				else
487dd7cddfSDavid du Colombier 					Bprint(bioout, "%-8ud      %s\n",
497dd7cddfSDavid du Colombier 						i->count, i->name);
507dd7cddfSDavid du Colombier 
517dd7cddfSDavid du Colombier 
527dd7cddfSDavid du Colombier 				switch(i->type) {
537dd7cddfSDavid du Colombier 				default:
547dd7cddfSDavid du Colombier 					fatal(0, "isum bad stype %d\n", i->type);
5580ee5cbfSDavid du Colombier 				case Imem:
5680ee5cbfSDavid du Colombier 					mems += i->count;
577dd7cddfSDavid du Colombier 					break;
587dd7cddfSDavid du Colombier 				case Iarith:
597dd7cddfSDavid du Colombier 					arith += i->count;
607dd7cddfSDavid du Colombier 					break;
617dd7cddfSDavid du Colombier 				case Ibranch:
627dd7cddfSDavid du Colombier 					branch += i->count;
637dd7cddfSDavid du Colombier 					taken += i->taken;
647dd7cddfSDavid du Colombier 					useddelay += i->useddelay;
657dd7cddfSDavid du Colombier 					break;
667dd7cddfSDavid du Colombier 				case Isyscall:
677dd7cddfSDavid du Colombier 					syscall += i->count;
687dd7cddfSDavid du Colombier 					break;
697dd7cddfSDavid du Colombier 				}
707dd7cddfSDavid du Colombier 
717dd7cddfSDavid du Colombier 			}
727dd7cddfSDavid du Colombier 		}
737dd7cddfSDavid du Colombier 	}
747dd7cddfSDavid du Colombier 
7580ee5cbfSDavid du Colombier 	Bprint(bioout, "\n%-8ud      Memory cycles\n", mems+total);
767dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Instruction cycles\n",
7780ee5cbfSDavid du Colombier 			total, Percent(total, mems+total));
787dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Data cycles\n\n",
7980ee5cbfSDavid du Colombier 			mems, Percent(mems, mems+total));
807dd7cddfSDavid du Colombier 
817dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Arithmetic\n",
827dd7cddfSDavid du Colombier 			arith, Percent(arith, total));
837dd7cddfSDavid du Colombier 
847dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% System calls\n",
857dd7cddfSDavid du Colombier 			syscall, Percent(syscall, total));
867dd7cddfSDavid du Colombier 
877dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Branches\n",
887dd7cddfSDavid du Colombier 			branch, Percent(branch, total));
897dd7cddfSDavid du Colombier 
907dd7cddfSDavid du Colombier 	Bprint(bioout, "   %-8ud %3d%% Branches taken\n",
917dd7cddfSDavid du Colombier 			taken, Percent(taken, branch));
927dd7cddfSDavid du Colombier 
937dd7cddfSDavid du Colombier 	Bprint(bioout, "   %-8ud %3d%% Delay slots\n",
947dd7cddfSDavid du Colombier 			useddelay, Percent(useddelay, branch));
957dd7cddfSDavid du Colombier 
967dd7cddfSDavid du Colombier 	Bprint(bioout, "   %-8ud %3d%% Unused delay slots\n",
977dd7cddfSDavid du Colombier 			branch-useddelay, Percent(branch-useddelay, branch));
987dd7cddfSDavid du Colombier 
997dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Program total delay slots\n",
1007dd7cddfSDavid du Colombier 			nopcount, Percent(nopcount, total));
1017dd7cddfSDavid du Colombier }
1027dd7cddfSDavid du Colombier 
1037dd7cddfSDavid du Colombier void
tlbsum(void)1047dd7cddfSDavid du Colombier tlbsum(void)
1057dd7cddfSDavid du Colombier {
1067dd7cddfSDavid du Colombier 	if(tlb.on == 0)
1077dd7cddfSDavid du Colombier 		return;
1087dd7cddfSDavid du Colombier 
1097dd7cddfSDavid du Colombier 	Bprint(bioout, "\n\nTlb summary\n");
1107dd7cddfSDavid du Colombier 
1117dd7cddfSDavid du Colombier 	Bprint(bioout, "\n%-8d User entries\n", tlb.tlbsize);
1127dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8d Accesses\n", tlb.hit+tlb.miss);
1137dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8d Tlb hits\n", tlb.hit);
1147dd7cddfSDavid du Colombier 	Bprint(bioout, "%-8d Tlb misses\n", tlb.miss);
1157dd7cddfSDavid du Colombier 	Bprint(bioout, "%7d%% Hit rate\n", Percent(tlb.hit, tlb.hit+tlb.miss));
1167dd7cddfSDavid du Colombier }
1177dd7cddfSDavid du Colombier 
1187dd7cddfSDavid du Colombier char *stype[] = { "Stack", "Text", "Data", "Bss" };
1197dd7cddfSDavid du Colombier 
1207dd7cddfSDavid du Colombier void
segsum(void)1217dd7cddfSDavid du Colombier segsum(void)
1227dd7cddfSDavid du Colombier {
1237dd7cddfSDavid du Colombier 	Segment *s;
1247dd7cddfSDavid du Colombier 	int i;
1257dd7cddfSDavid du Colombier 
1267dd7cddfSDavid du Colombier 	Bprint(bioout, "\n\nMemory Summary\n\n");
1277dd7cddfSDavid du Colombier 	Bprint(bioout, "      Base     End      Resident References\n");
1287dd7cddfSDavid du Colombier 	for(i = 0; i < Nseg; i++) {
1297dd7cddfSDavid du Colombier 		s = &memory.seg[i];
1307dd7cddfSDavid du Colombier 		Bprint(bioout, "%-5s %.8lux %.8lux %-8d %-8d\n",
1317dd7cddfSDavid du Colombier 				stype[i], s->base, s->end, s->rss*BY2PG, s->refs);
1327dd7cddfSDavid du Colombier 	}
1337dd7cddfSDavid du Colombier }
1347dd7cddfSDavid du Colombier 
1357dd7cddfSDavid du Colombier typedef struct Prof Prof;
1367dd7cddfSDavid du Colombier struct Prof
1377dd7cddfSDavid du Colombier {
1387dd7cddfSDavid du Colombier 	Symbol	s;
1397dd7cddfSDavid du Colombier 	long	count;
1407dd7cddfSDavid du Colombier };
1417dd7cddfSDavid du Colombier Prof	prof[5000];
1427dd7cddfSDavid du Colombier 
1437dd7cddfSDavid du Colombier int
profcmp(void * va,void * vb)1447dd7cddfSDavid du Colombier profcmp(void *va, void *vb)
1457dd7cddfSDavid du Colombier {
1467dd7cddfSDavid du Colombier 	Prof *a, *b;
1477dd7cddfSDavid du Colombier 
1487dd7cddfSDavid du Colombier 	a = va;
1497dd7cddfSDavid du Colombier 	b = vb;
1507dd7cddfSDavid du Colombier 	return b->count - a->count;
1517dd7cddfSDavid du Colombier }
1527dd7cddfSDavid du Colombier 
1537dd7cddfSDavid du Colombier void
iprofile(void)1547dd7cddfSDavid du Colombier iprofile(void)
1557dd7cddfSDavid du Colombier {
1567dd7cddfSDavid du Colombier 	Prof *p, *n;
1577dd7cddfSDavid du Colombier 	int i, b, e;
1587dd7cddfSDavid du Colombier 	ulong total;
1597dd7cddfSDavid du Colombier 	extern ulong textbase;
1607dd7cddfSDavid du Colombier 
1617dd7cddfSDavid du Colombier 	i = 0;
1627dd7cddfSDavid du Colombier 	p = prof;
1637dd7cddfSDavid du Colombier 	if(textsym(&p->s, i) == 0)
1647dd7cddfSDavid du Colombier 		return;
1657dd7cddfSDavid du Colombier 	i++;
1667dd7cddfSDavid du Colombier 	for(;;) {
1677dd7cddfSDavid du Colombier 		n = p+1;
1687dd7cddfSDavid du Colombier 		if(textsym(&n->s, i) == 0)
1697dd7cddfSDavid du Colombier 			break;
1707dd7cddfSDavid du Colombier 		b = (p->s.value-textbase)/PROFGRAN;
1717dd7cddfSDavid du Colombier 		e = (n->s.value-textbase)/PROFGRAN;
1727dd7cddfSDavid du Colombier 		while(b < e)
1737dd7cddfSDavid du Colombier 			p->count += iprof[b++];
1747dd7cddfSDavid du Colombier 		i++;
1757dd7cddfSDavid du Colombier 		p = n;
1767dd7cddfSDavid du Colombier 	}
1777dd7cddfSDavid du Colombier 
1787dd7cddfSDavid du Colombier 	qsort(prof, i, sizeof(Prof), profcmp);
1797dd7cddfSDavid du Colombier 
1807dd7cddfSDavid du Colombier 	total = 0;
1817dd7cddfSDavid du Colombier 	for(b = 0; b < i; b++)
1827dd7cddfSDavid du Colombier 		total += prof[b].count;
1837dd7cddfSDavid du Colombier 
1847dd7cddfSDavid du Colombier 	Bprint(bioout, "  cycles     %% symbol          file\n");
1857dd7cddfSDavid du Colombier 	for(b = 0; b < i; b++) {
1867dd7cddfSDavid du Colombier 		if(prof[b].count == 0)
1877dd7cddfSDavid du Colombier 			continue;
1887dd7cddfSDavid du Colombier 
1897dd7cddfSDavid du Colombier 		Bprint(bioout, "%8ld %3ld.%ld %-15s ",
1907dd7cddfSDavid du Colombier 			prof[b].count,
1917dd7cddfSDavid du Colombier 			100*prof[b].count/total,
1927dd7cddfSDavid du Colombier 			(1000*prof[b].count/total)%10,
1937dd7cddfSDavid du Colombier 			prof[b].s.name);
1947dd7cddfSDavid du Colombier 
1957dd7cddfSDavid du Colombier 		printsource(prof[b].s.value);
1967dd7cddfSDavid du Colombier 		Bputc(bioout, '\n');
1977dd7cddfSDavid du Colombier 	}
1987dd7cddfSDavid du Colombier 	memset(prof, 0, sizeof(Prof)*i);
1997dd7cddfSDavid du Colombier }
200