]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/qi/stats.c
webfs(4): document -d and -D flags
[plan9front.git] / sys / src / cmd / qi / stats.c
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         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
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(void *a, void *b)
159 {
160         return ((Prof*)b)->count - ((Prof*)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, "%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 }