xref: /plan9/sys/src/cmd/qi/stats.c (revision 6891d8578618fb7ccda4a131c122d4d0e6580c4b)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <mach.h>
5 #define Extern extern
6 #include "power.h"
7 
8 #define	prof profqi
9 #define Percent(num, max)	(int)(((vlong)(num)*100)/(max))
10 
11 Inset *tables[] = { &ops0, &ops19, &ops31, &ops59, &ops63a, &ops63b, 0 };
12 
13 void
isum(void)14 isum(void)
15 {
16 	Inst *i;
17 	int pct, j, k;
18 	int total, loads, stores, arith, branch;
19 	int taken, powerreg, syscall, realarith, control;
20 
21 	total = 0;
22 	loads = 0;
23 	stores = 0;
24 	arith = 0;
25 	branch = 0;
26 	taken = 0;
27 	powerreg = 0;
28 	syscall = 0;
29 	realarith = 0;
30 	control = 0;
31 
32 	/* Compute the total so we can have percentages */
33 	for(j = 0; tables[j]; j++)
34 		for(k = tables[j]->nel; --k >= 0;) {
35 			i = &tables[j]->tab[k];
36 			if(i->name && i->func)
37 				total += i->count;
38 		}
39 
40 	Bprint(bioout, "\nInstruction summary.\n\n");
41 
42 	for(j = 0; tables[j]; j++) {
43 		for(k =tables[j]->nel; --k>=0; ) {
44 			i = &tables[j]->tab[k];
45 			if(i->name && i->func) {
46 				if(i->count == 0)
47 					continue;
48 				pct = Percent(i->count, total);
49 				if(pct != 0)
50 					Bprint(bioout, "%-8ud %3d%% %s\n",
51 					i->count, Percent(i->count, total), i->name);
52 				else
53 					Bprint(bioout, "%-8ud      %s\n",
54 					i->count, i->name);
55 
56 				switch(i->type) {
57 				default:
58 					fatal(0, "isum bad stype %d\n", i->type);
59 				case Iload:
60 					loads += i->count;
61 					break;
62 				case Istore:
63 					stores += i->count;
64 					break;
65 				case Ilog:
66 				case Iarith:
67 					arith += i->count;
68 					break;
69 				case Ibranch:
70 					branch += i->count;
71 					taken += i->taken;
72 					break;
73 				case Ireg:
74 					powerreg += i->count;
75 					break;
76 				case Isyscall:
77 					syscall += i->count;
78 					break;
79 				case Ifloat:
80 					realarith += i->count;
81 					break;
82 				case Inop:
83 					arith += i->count;
84 					i->count -= nopcount;
85 					break;
86 				case Icontrol:
87 					control += i->count;
88 					break;
89 				}
90 			}
91 		}
92 	}
93 
94 	Bprint(bioout, "\n%-8ud      Memory cycles\n", loads+stores+total);
95 
96 	if(total == 0)
97 		return;
98 
99 	Bprint(bioout, "%-8ud %3d%% Instruction cycles\n",
100 				total, Percent(total, loads+stores+total));
101 
102 	Bprint(bioout, "%-8ud %3d%% Data cycles\n\n",
103 				loads+stores, Percent(loads+stores, loads+stores+total));
104 
105 	Bprint(bioout, "%-8ud %3d%% Stores\n", stores, Percent(stores, total));
106 
107 	Bprint(bioout, "%-8ud %3d%% Loads\n", loads, Percent(loads, total));
108 
109 	Bprint(bioout, "   %-8ud Store stall\n", stores*2);
110 
111 	Bprint(bioout, "   %-8lud Load stall\n", loadlock);
112 
113 	Bprint(bioout, "%-8ud %3d%% Arithmetic\n", arith, Percent(arith, total));
114 
115 	Bprint(bioout, "%-8ud %3d%% Floating point\n",
116 					realarith, Percent(realarith, total));
117 
118 	Bprint(bioout, "%-8ud %3d%% PowerPC special register load/stores\n",
119 					powerreg, Percent(powerreg, total));
120 
121 	Bprint(bioout, "%-8ud %3d%% PowerPC control instructions\n",
122 					control, Percent(control, total));
123 
124 	Bprint(bioout, "%-8ud %3d%% System calls\n", syscall, Percent(syscall, total));
125 
126 	Bprint(bioout, "%-8ud %3d%% Branches\n", branch, Percent(branch, total));
127 
128 	Bprint(bioout, "   %-8ud %3d%% Branches taken\n",
129 					taken, Percent(taken, branch));
130 }
131 
132 char *stype[] = { "Stack", "Text", "Data", "Bss" };
133 
134 void
segsum(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
profcmp(void * a,void * b)158 profcmp(void *a, void *b)
159 {
160 	return ((Prof*)b)->count - ((Prof*)a)->count;
161 }
162 
163 void
iprofile(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, "%8ld %3ld.%ld %-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