xref: /plan9/sys/src/cmd/qi/stats.c (revision 6891d8578618fb7ccda4a131c122d4d0e6580c4b)
17d9195a7SDavid du Colombier #include <u.h>
27d9195a7SDavid du Colombier #include <libc.h>
37d9195a7SDavid du Colombier #include <bio.h>
47d9195a7SDavid du Colombier #include <mach.h>
57d9195a7SDavid du Colombier #define Extern extern
67d9195a7SDavid du Colombier #include "power.h"
77d9195a7SDavid du Colombier 
87d9195a7SDavid du Colombier #define	prof profqi
97d9195a7SDavid du Colombier #define Percent(num, max)	(int)(((vlong)(num)*100)/(max))
107d9195a7SDavid du Colombier 
117d9195a7SDavid du Colombier Inset *tables[] = { &ops0, &ops19, &ops31, &ops59, &ops63a, &ops63b, 0 };
127d9195a7SDavid du Colombier 
137d9195a7SDavid du Colombier void
isum(void)147d9195a7SDavid du Colombier isum(void)
157d9195a7SDavid du Colombier {
167d9195a7SDavid du Colombier 	Inst *i;
177d9195a7SDavid du Colombier 	int pct, j, k;
187d9195a7SDavid du Colombier 	int total, loads, stores, arith, branch;
197d9195a7SDavid du Colombier 	int taken, powerreg, syscall, realarith, control;
207d9195a7SDavid du Colombier 
217d9195a7SDavid du Colombier 	total = 0;
227d9195a7SDavid du Colombier 	loads = 0;
237d9195a7SDavid du Colombier 	stores = 0;
247d9195a7SDavid du Colombier 	arith = 0;
257d9195a7SDavid du Colombier 	branch = 0;
267d9195a7SDavid du Colombier 	taken = 0;
277d9195a7SDavid du Colombier 	powerreg = 0;
287d9195a7SDavid du Colombier 	syscall = 0;
297d9195a7SDavid du Colombier 	realarith = 0;
307d9195a7SDavid du Colombier 	control = 0;
317d9195a7SDavid du Colombier 
327d9195a7SDavid du Colombier 	/* Compute the total so we can have percentages */
337d9195a7SDavid du Colombier 	for(j = 0; tables[j]; j++)
347d9195a7SDavid du Colombier 		for(k = tables[j]->nel; --k >= 0;) {
357d9195a7SDavid du Colombier 			i = &tables[j]->tab[k];
367d9195a7SDavid du Colombier 			if(i->name && i->func)
377d9195a7SDavid du Colombier 				total += i->count;
387d9195a7SDavid du Colombier 		}
397d9195a7SDavid du Colombier 
407d9195a7SDavid du Colombier 	Bprint(bioout, "\nInstruction summary.\n\n");
417d9195a7SDavid du Colombier 
427d9195a7SDavid du Colombier 	for(j = 0; tables[j]; j++) {
437d9195a7SDavid du Colombier 		for(k =tables[j]->nel; --k>=0; ) {
447d9195a7SDavid du Colombier 			i = &tables[j]->tab[k];
457d9195a7SDavid du Colombier 			if(i->name && i->func) {
467d9195a7SDavid du Colombier 				if(i->count == 0)
477d9195a7SDavid du Colombier 					continue;
487d9195a7SDavid du Colombier 				pct = Percent(i->count, total);
497d9195a7SDavid du Colombier 				if(pct != 0)
507d9195a7SDavid du Colombier 					Bprint(bioout, "%-8ud %3d%% %s\n",
517d9195a7SDavid du Colombier 					i->count, Percent(i->count, total), i->name);
527d9195a7SDavid du Colombier 				else
537d9195a7SDavid du Colombier 					Bprint(bioout, "%-8ud      %s\n",
547d9195a7SDavid du Colombier 					i->count, i->name);
557d9195a7SDavid du Colombier 
567d9195a7SDavid du Colombier 				switch(i->type) {
577d9195a7SDavid du Colombier 				default:
587d9195a7SDavid du Colombier 					fatal(0, "isum bad stype %d\n", i->type);
597d9195a7SDavid du Colombier 				case Iload:
607d9195a7SDavid du Colombier 					loads += i->count;
617d9195a7SDavid du Colombier 					break;
627d9195a7SDavid du Colombier 				case Istore:
637d9195a7SDavid du Colombier 					stores += i->count;
647d9195a7SDavid du Colombier 					break;
657d9195a7SDavid du Colombier 				case Ilog:
667d9195a7SDavid du Colombier 				case Iarith:
677d9195a7SDavid du Colombier 					arith += i->count;
687d9195a7SDavid du Colombier 					break;
697d9195a7SDavid du Colombier 				case Ibranch:
707d9195a7SDavid du Colombier 					branch += i->count;
717d9195a7SDavid du Colombier 					taken += i->taken;
727d9195a7SDavid du Colombier 					break;
737d9195a7SDavid du Colombier 				case Ireg:
747d9195a7SDavid du Colombier 					powerreg += i->count;
757d9195a7SDavid du Colombier 					break;
767d9195a7SDavid du Colombier 				case Isyscall:
777d9195a7SDavid du Colombier 					syscall += i->count;
787d9195a7SDavid du Colombier 					break;
797d9195a7SDavid du Colombier 				case Ifloat:
807d9195a7SDavid du Colombier 					realarith += i->count;
817d9195a7SDavid du Colombier 					break;
827d9195a7SDavid du Colombier 				case Inop:
837d9195a7SDavid du Colombier 					arith += i->count;
847d9195a7SDavid du Colombier 					i->count -= nopcount;
857d9195a7SDavid du Colombier 					break;
867d9195a7SDavid du Colombier 				case Icontrol:
877d9195a7SDavid du Colombier 					control += i->count;
887d9195a7SDavid du Colombier 					break;
897d9195a7SDavid du Colombier 				}
907d9195a7SDavid du Colombier 			}
917d9195a7SDavid du Colombier 		}
927d9195a7SDavid du Colombier 	}
937d9195a7SDavid du Colombier 
947d9195a7SDavid du Colombier 	Bprint(bioout, "\n%-8ud      Memory cycles\n", loads+stores+total);
957d9195a7SDavid du Colombier 
96*6891d857SDavid du Colombier 	if(total == 0)
97*6891d857SDavid du Colombier 		return;
98*6891d857SDavid du Colombier 
997d9195a7SDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Instruction cycles\n",
1007d9195a7SDavid du Colombier 				total, Percent(total, loads+stores+total));
1017d9195a7SDavid du Colombier 
1027d9195a7SDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Data cycles\n\n",
1037d9195a7SDavid du Colombier 				loads+stores, Percent(loads+stores, loads+stores+total));
1047d9195a7SDavid du Colombier 
1057d9195a7SDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Stores\n", stores, Percent(stores, total));
1067d9195a7SDavid du Colombier 
1077d9195a7SDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Loads\n", loads, Percent(loads, total));
1087d9195a7SDavid du Colombier 
1097d9195a7SDavid du Colombier 	Bprint(bioout, "   %-8ud Store stall\n", stores*2);
1107d9195a7SDavid du Colombier 
1117d9195a7SDavid du Colombier 	Bprint(bioout, "   %-8lud Load stall\n", loadlock);
1127d9195a7SDavid du Colombier 
1137d9195a7SDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Arithmetic\n", arith, Percent(arith, total));
1147d9195a7SDavid du Colombier 
1157d9195a7SDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Floating point\n",
1167d9195a7SDavid du Colombier 					realarith, Percent(realarith, total));
1177d9195a7SDavid du Colombier 
1187d9195a7SDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% PowerPC special register load/stores\n",
1197d9195a7SDavid du Colombier 					powerreg, Percent(powerreg, total));
1207d9195a7SDavid du Colombier 
1217d9195a7SDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% PowerPC control instructions\n",
1227d9195a7SDavid du Colombier 					control, Percent(control, total));
1237d9195a7SDavid du Colombier 
1247d9195a7SDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% System calls\n", syscall, Percent(syscall, total));
1257d9195a7SDavid du Colombier 
1267d9195a7SDavid du Colombier 	Bprint(bioout, "%-8ud %3d%% Branches\n", branch, Percent(branch, total));
1277d9195a7SDavid du Colombier 
1287d9195a7SDavid du Colombier 	Bprint(bioout, "   %-8ud %3d%% Branches taken\n",
1297d9195a7SDavid du Colombier 					taken, Percent(taken, branch));
1307d9195a7SDavid du Colombier }
1317d9195a7SDavid du Colombier 
1327d9195a7SDavid du Colombier char *stype[] = { "Stack", "Text", "Data", "Bss" };
1337d9195a7SDavid du Colombier 
1347d9195a7SDavid du Colombier void
segsum(void)1357d9195a7SDavid du Colombier segsum(void)
1367d9195a7SDavid du Colombier {
1377d9195a7SDavid du Colombier 	Segment *s;
1387d9195a7SDavid du Colombier 	int i;
1397d9195a7SDavid du Colombier 
1407d9195a7SDavid du Colombier 	Bprint(bioout, "\n\nMemory Summary\n\n");
1417d9195a7SDavid du Colombier 	Bprint(bioout, "      Base     End      Resident References\n");
1427d9195a7SDavid du Colombier 	for(i = 0; i < Nseg; i++) {
1437d9195a7SDavid du Colombier 		s = &memory.seg[i];
1447d9195a7SDavid du Colombier 		Bprint(bioout, "%-5s %.8lux %.8lux %-8d %-8d\n",
1457d9195a7SDavid du Colombier 				stype[i], s->base, s->end, s->rss*BY2PG, s->refs);
1467d9195a7SDavid du Colombier 	}
1477d9195a7SDavid du Colombier }
1487d9195a7SDavid du Colombier 
1497d9195a7SDavid du Colombier typedef struct Prof Prof;
1507d9195a7SDavid du Colombier struct Prof
1517d9195a7SDavid du Colombier {
1527d9195a7SDavid du Colombier 	Symbol	s;
1537d9195a7SDavid du Colombier 	long	count;
1547d9195a7SDavid du Colombier };
1557d9195a7SDavid du Colombier Prof	prof[5000];
1567d9195a7SDavid du Colombier 
1577d9195a7SDavid du Colombier int
profcmp(void * a,void * b)1587d9195a7SDavid du Colombier profcmp(void *a, void *b)
1597d9195a7SDavid du Colombier {
1607d9195a7SDavid du Colombier 	return ((Prof*)b)->count - ((Prof*)a)->count;
1617d9195a7SDavid du Colombier }
1627d9195a7SDavid du Colombier 
1637d9195a7SDavid du Colombier void
iprofile(void)1647d9195a7SDavid du Colombier iprofile(void)
1657d9195a7SDavid du Colombier {
1667d9195a7SDavid du Colombier 	Prof *p, *n;
1677d9195a7SDavid du Colombier 	int i, b, e;
1687d9195a7SDavid du Colombier 	ulong total;
1697d9195a7SDavid du Colombier 	extern ulong textbase;
1707d9195a7SDavid du Colombier 
1717d9195a7SDavid du Colombier 	i = 0;
1727d9195a7SDavid du Colombier 	p = prof;
1737d9195a7SDavid du Colombier 	if(textsym(&p->s, i) == 0)
1747d9195a7SDavid du Colombier 		return;
1757d9195a7SDavid du Colombier 	i++;
1767d9195a7SDavid du Colombier 	for(;;) {
1777d9195a7SDavid du Colombier 		n = p+1;
1787d9195a7SDavid du Colombier 		if(textsym(&n->s, i) == 0)
1797d9195a7SDavid du Colombier 			break;
1807d9195a7SDavid du Colombier 		b = (p->s.value-textbase)/PROFGRAN;
1817d9195a7SDavid du Colombier 		e = (n->s.value-textbase)/PROFGRAN;
1827d9195a7SDavid du Colombier 		while(b < e)
1837d9195a7SDavid du Colombier 			p->count += iprof[b++];
1847d9195a7SDavid du Colombier 		i++;
1857d9195a7SDavid du Colombier 		p = n;
1867d9195a7SDavid du Colombier 	}
1877d9195a7SDavid du Colombier 
1887d9195a7SDavid du Colombier 	qsort(prof, i, sizeof(Prof), profcmp);
1897d9195a7SDavid du Colombier 
1907d9195a7SDavid du Colombier 	total = 0;
1917d9195a7SDavid du Colombier 	for(b = 0; b < i; b++)
1927d9195a7SDavid du Colombier 		total += prof[b].count;
1937d9195a7SDavid du Colombier 
1947d9195a7SDavid du Colombier 	Bprint(bioout, "  cycles     %% symbol          file\n");
1957d9195a7SDavid du Colombier 	for(b = 0; b < i; b++) {
1967d9195a7SDavid du Colombier 		if(prof[b].count == 0)
1977d9195a7SDavid du Colombier 			continue;
1987d9195a7SDavid du Colombier 
1997d9195a7SDavid du Colombier 		Bprint(bioout, "%8ld %3ld.%ld %-15s ",
2007d9195a7SDavid du Colombier 			prof[b].count,
2017d9195a7SDavid du Colombier 			100*prof[b].count/total,
2027d9195a7SDavid du Colombier 			(1000*prof[b].count/total)%10,
2037d9195a7SDavid du Colombier 			prof[b].s.name);
2047d9195a7SDavid du Colombier 
2057d9195a7SDavid du Colombier 		printsource(prof[b].s.value);
2067d9195a7SDavid du Colombier 		Bputc(bioout, '\n');
2077d9195a7SDavid du Colombier 	}
2087d9195a7SDavid du Colombier 	memset(prof, 0, sizeof(Prof)*i);
2097d9195a7SDavid du Colombier }
210