xref: /plan9-contrib/sys/src/cmd/ki/stats.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <mach.h>
5 #define Extern extern
6 #include "sparc.h"
7 
8 #define Percent(num, max)	(((num)*100)/(max))
9 
10 extern Inst op0[], op2[], op3[];
11 Inst *tables[] = { op0, op2, op3, 0 };
12 
13 void
14 isum(void)
15 {
16 	Inst *i;
17 	int pct, j;
18 	int total, loads, stores, arith, branch;
19 	int useddelay, taken, sparcreg, syscall, realarith;
20 
21 	total = 0;
22 	loads = 0;
23 	stores = 0;
24 	arith = 0;
25 	branch = 0;
26 	useddelay = 0;
27 	taken = 0;
28 	sparcreg = 0;
29 	syscall = 0;
30 	realarith = 0;
31 
32 	/* Compute the total so we can have percentages */
33 	for(j = 0; tables[j]; j++)
34 		for(i = tables[j]; i->func; i++)
35 			if(i->name && i->count)
36 				total += i->count;
37 
38 	Bprint(bioout, "\nInstruction summary.\n\n");
39 
40 	for(j = 0; tables[j]; j++) {
41 		for(i =tables[j]; i->func; i++) {
42 			if(i->name) {
43 				if(i->count == 0)
44 					continue;
45 				pct = Percent(i->count, total);
46 				if(pct != 0)
47 					Bprint(bioout, "%-8lud %3d%% %s\n",
48 					i->count, Percent(i->count, total), i->name);
49 				else
50 					Bprint(bioout, "%-8lud      %s\n",
51 					i->count, i->name);
52 
53 				switch(i->type) {
54 				default:
55 					fatal(0, "isum bad stype %d\n", i->type);
56 				case Iload:
57 					loads += i->count;
58 					break;
59 				case Istore:
60 					stores += i->count;
61 					break;
62 				case Iarith:
63 					arith += i->count;
64 					break;
65 				case Ibranch:
66 					branch += i->count;
67 					taken += i->taken;
68 					useddelay += i->useddelay;
69 					break;
70 				case Ireg:
71 					sparcreg += i->count;
72 					break;
73 				case Isyscall:
74 					syscall += i->count;
75 					break;
76 				case Ifloat:
77 					realarith += i->count;
78 					break;
79 				case Inop:
80 					arith += i->count;
81 					i->count -= nopcount;
82 					break;
83 				}
84 			}
85 		}
86 	}
87 
88 	total += anulled;
89 	Bprint(bioout, "\n%-8lud      Memory cycles\n", loads+stores+total);
90 
91 	Bprint(bioout, "%-8lud %3d%% Instruction cycles\n",
92 				total, Percent(total, loads+stores+total));
93 	Bprint(bioout, "%-8lud %3d%% Annulled branch cycles\n",
94 				anulled, Percent(anulled, total));
95 
96 	Bprint(bioout, "%-8lud %3d%% Data cycles\n\n",
97 				loads+stores, Percent(loads+stores, loads+stores+total));
98 
99 	Bprint(bioout, "%-8lud %3d%% Stores\n", stores, Percent(stores, total));
100 
101 	Bprint(bioout, "%-8lud %3d%% Loads\n", loads, Percent(loads, total));
102 
103 	Bprint(bioout, "   %-8lud Store stall\n", stores*2);
104 
105 	Bprint(bioout, "   %-8lud Load stall\n", loadlock);
106 
107 	Bprint(bioout, "%-8lud %3d%% Arithmetic\n", arith, Percent(arith, total));
108 
109 	Bprint(bioout, "%-8lud %3d%% Floating point\n",
110 					realarith, Percent(realarith, total));
111 
112 	Bprint(bioout, "%-8lud %3d%% Sparc special register load/stores\n",
113 					sparcreg, Percent(sparcreg, total));
114 
115 	Bprint(bioout, "%-8lud %3d%% System calls\n", syscall, Percent(syscall, total));
116 
117 	Bprint(bioout, "%-8lud %3d%% Branches\n", branch, Percent(branch, total));
118 
119 	Bprint(bioout, "   %-8lud %3d%% Branches taken\n",
120 					taken, Percent(taken, branch));
121 
122 	Bprint(bioout, "   %-8lud %3d%% Delay slots\n",
123 					useddelay, Percent(useddelay, branch));
124 
125 	Bprint(bioout, "   %-8lud %3d%% Unused delay slots\n",
126 					nopcount, Percent(nopcount, branch));
127 
128 	Bprint(bioout, "%-8lud %3d%% Program total delay slots\n",
129 					nopcount, Percent(nopcount, total));
130 }
131 
132 char *stype[] = { "Stack", "Text", "Data", "Bss" };
133 
134 void
135 segsum(void)
136 {
137 	Segment *s;
138 	int i;
139 
140 	Bprint(bioout, "\n\nMemory Summary\n\n");
141 	Bprint(bioout, "      Base     End      Resident References\n");
142 	for(i = 0; i < Nseg; i++) {
143 		s = &memory.seg[i];
144 		Bprint(bioout, "%-5s %.8lux %.8lux %-8d %-8d\n",
145 				stype[i], s->base, s->end, s->rss*BY2PG, s->refs);
146 	}
147 }
148 
149 typedef struct Prof Prof;
150 struct Prof
151 {
152 	Symbol	s;
153 	long	count;
154 };
155 Prof	prof[5000];
156 
157 int
158 profcmp(Prof *a, Prof *b)
159 {
160 	return b->count - a->count;
161 }
162 
163 void
164 iprofile(void)
165 {
166 	Prof *p, *n;
167 	int i, b, e;
168 	ulong total;
169 	extern ulong textbase;
170 
171 	i = 0;
172 	p = prof;
173 	if(textsym(&p->s, i) == 0)
174 		return;
175 	i++;
176 	for(;;) {
177 		n = p+1;
178 		if(textsym(&n->s, i) == 0)
179 			break;
180 		b = (p->s.value-textbase)/PROFGRAN;
181 		e = (n->s.value-textbase)/PROFGRAN;
182 		while(b < e)
183 			p->count += iprof[b++];
184 		i++;
185 		p = n;
186 	}
187 
188 	qsort(prof, i, sizeof(Prof), profcmp);
189 
190 	total = 0;
191 	for(b = 0; b < i; b++)
192 		total += prof[b].count;
193 
194 	Bprint(bioout, "  cycles     %% symbol          file\n");
195 	for(b = 0; b < i; b++) {
196 		if(prof[b].count == 0)
197 			continue;
198 
199 		Bprint(bioout, "%8d %3ld.%d %-15s ",
200 			prof[b].count,
201 			100*prof[b].count/total,
202 			(1000*prof[b].count/total)%10,
203 			prof[b].s.name);
204 
205 		printsource(prof[b].s.value);
206 		Bputc(bioout, '\n');
207 	}
208 	memset(prof, 0, sizeof(Prof)*i);
209 }
210