xref: /plan9/sys/src/cmd/qi/stats.c (revision ec59a3ddbfceee0efe34584c2c9981a5e5ff1ec4)
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
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 	Bprint(bioout, "%-8ud %3d%% Instruction cycles\n",
97 				total, Percent(total, loads+stores+total));
98 
99 	Bprint(bioout, "%-8ud %3d%% Data cycles\n\n",
100 				loads+stores, Percent(loads+stores, loads+stores+total));
101 
102 	Bprint(bioout, "%-8ud %3d%% Stores\n", stores, Percent(stores, total));
103 
104 	Bprint(bioout, "%-8ud %3d%% Loads\n", loads, Percent(loads, total));
105 
106 	Bprint(bioout, "   %-8ud Store stall\n", stores*2);
107 
108 	Bprint(bioout, "   %-8lud Load stall\n", loadlock);
109 
110 	Bprint(bioout, "%-8ud %3d%% Arithmetic\n", arith, Percent(arith, total));
111 
112 	Bprint(bioout, "%-8ud %3d%% Floating point\n",
113 					realarith, Percent(realarith, total));
114 
115 	Bprint(bioout, "%-8ud %3d%% PowerPC special register load/stores\n",
116 					powerreg, Percent(powerreg, total));
117 
118 	Bprint(bioout, "%-8ud %3d%% PowerPC control instructions\n",
119 					control, Percent(control, total));
120 
121 	Bprint(bioout, "%-8ud %3d%% System calls\n", syscall, Percent(syscall, total));
122 
123 	Bprint(bioout, "%-8ud %3d%% Branches\n", branch, Percent(branch, total));
124 
125 	Bprint(bioout, "   %-8ud %3d%% Branches taken\n",
126 					taken, Percent(taken, branch));
127 }
128 
129 char *stype[] = { "Stack", "Text", "Data", "Bss" };
130 
131 void
132 segsum(void)
133 {
134 	Segment *s;
135 	int i;
136 
137 	Bprint(bioout, "\n\nMemory Summary\n\n");
138 	Bprint(bioout, "      Base     End      Resident References\n");
139 	for(i = 0; i < Nseg; i++) {
140 		s = &memory.seg[i];
141 		Bprint(bioout, "%-5s %.8lux %.8lux %-8d %-8d\n",
142 				stype[i], s->base, s->end, s->rss*BY2PG, s->refs);
143 	}
144 }
145 
146 typedef struct Prof Prof;
147 struct Prof
148 {
149 	Symbol	s;
150 	long	count;
151 };
152 Prof	prof[5000];
153 
154 int
155 profcmp(void *a, void *b)
156 {
157 	return ((Prof*)b)->count - ((Prof*)a)->count;
158 }
159 
160 void
161 iprofile(void)
162 {
163 	Prof *p, *n;
164 	int i, b, e;
165 	ulong total;
166 	extern ulong textbase;
167 
168 	i = 0;
169 	p = prof;
170 	if(textsym(&p->s, i) == 0)
171 		return;
172 	i++;
173 	for(;;) {
174 		n = p+1;
175 		if(textsym(&n->s, i) == 0)
176 			break;
177 		b = (p->s.value-textbase)/PROFGRAN;
178 		e = (n->s.value-textbase)/PROFGRAN;
179 		while(b < e)
180 			p->count += iprof[b++];
181 		i++;
182 		p = n;
183 	}
184 
185 	qsort(prof, i, sizeof(Prof), profcmp);
186 
187 	total = 0;
188 	for(b = 0; b < i; b++)
189 		total += prof[b].count;
190 
191 	Bprint(bioout, "  cycles     %% symbol          file\n");
192 	for(b = 0; b < i; b++) {
193 		if(prof[b].count == 0)
194 			continue;
195 
196 		Bprint(bioout, "%8ld %3ld.%ld %-15s ",
197 			prof[b].count,
198 			100*prof[b].count/total,
199 			(1000*prof[b].count/total)%10,
200 			prof[b].s.name);
201 
202 		printsource(prof[b].s.value);
203 		Bputc(bioout, '\n');
204 	}
205 	memset(prof, 0, sizeof(Prof)*i);
206 }
207