xref: /inferno-os/doc/lprof.ms (revision 46439007cf417cbd9ac8049bb4122c890097a0fa)
1*46439007SCharles.Forsyth.TL
2*46439007SCharles.ForsythLimbo profilers in Inferno
3*46439007SCharles.Forsyth.AU
4*46439007SCharles.ForsythJ R Firth
5*46439007SCharles.Forsyth.AI
6*46439007SCharles.ForsythVita Nuova
7*46439007SCharles.Forsyth.br
8*46439007SCharles.Forsyth13 June 2002
9*46439007SCharles.Forsyth.SP 4
10*46439007SCharles.Forsyth.NH 1
11*46439007SCharles.ForsythIntroduction
12*46439007SCharles.Forsyth.LP
13*46439007SCharles.ForsythCurrently there are three application level profiling tools in the
14*46439007SCharles.ForsythInferno package.
15*46439007SCharles.Forsyth.I Prof
16*46439007SCharles.Forsythis a time profiler which, by sampling, can provide statistics
17*46439007SCharles.Forsython the percentage of time spent on each line of limbo source.
18*46439007SCharles.Forsyth.I Cprof
19*46439007SCharles.Forsythis a
20*46439007SCharles.Forsythcoverage profiler which provides the execution profile for limbo source
21*46439007SCharles.Forsythcode. It can accumulate results over a series of runs to allow full
22*46439007SCharles.Forsythcoverage testing. Finally,
23*46439007SCharles.Forsyth.I mprof
24*46439007SCharles.Forsythis a memory profiler which provides
25*46439007SCharles.Forsythstatistics on the amount of memory used by each line
26*46439007SCharles.Forsythof limbo source.
27*46439007SCharles.Forsyth.LP
28*46439007SCharles.ForsythTwo gui versions of these tools currently exist.
29*46439007SCharles.Forsyth.I Wm/cprof
30*46439007SCharles.Forsythshows the
31*46439007SCharles.Forsythcoverage per module and highlights those lines which have not been
32*46439007SCharles.Forsythexecuted or have been only partially executed.
33*46439007SCharles.Forsyth.I Wm/mprof
34*46439007SCharles.Forsythshows the memory
35*46439007SCharles.Forsythusage per module and highlights lines with high memory allocation in
36*46439007SCharles.Forsythdarker shades of red.
37*46439007SCharles.Forsyth.I Prof
38*46439007SCharles.Forsythitself does not have a gui equivalent as it
39*46439007SCharles.Forsythwas originally written to determine why acme was so slow when using it's
40*46439007SCharles.Forsythglobal editing command. A gui for it was not a requirement at that stage.
41*46439007SCharles.Forsyth.LP
42*46439007SCharles.ForsythAll these tools use a common library module
43*46439007SCharles.Forsyth.CW /module/profile.m
44*46439007SCharles.Forsythand
45*46439007SCharles.Forsyth.CW /appl/lib/profile.b
46*46439007SCharles.Forsyththat acts as the direct interface with the kernel profiling device.
47*46439007SCharles.Forsyth.LP
48*46439007SCharles.ForsythNote that none of these tools give kernel profile statistics. For that, the devmem driver should be used.
49*46439007SCharles.Forsyth.LP
50*46439007SCharles.ForsythAlthough the use of these tools is very similar, there are a few differences
51*46439007SCharles.Forsythwhen it comes to interactive testing as the profilers were written to
52*46439007SCharles.Forsythanswer different questions. Thus
53*46439007SCharles.Forsyth.I prof
54*46439007SCharles.Forsythtries to determine 'why is blah so
55*46439007SCharles.Forsythslow ?',
56*46439007SCharles.Forsyth.I cprof
57*46439007SCharles.Forsythtries to accumulate coverage records over time and
58*46439007SCharles.Forsyth.I mprof
59*46439007SCharles.Forsythtries to
60*46439007SCharles.Forsythgive a series of memory statistics at intervals during the execution of
61*46439007SCharles.Forsytha program or series of programs.
62*46439007SCharles.Forsyth.NH 1
63*46439007SCharles.ForsythProf
64*46439007SCharles.Forsyth.LP
65*46439007SCharles.ForsythThe time profiler works by sampling. A kernel procedure sleeps for the
66*46439007SCharles.Forsythgiven sample time and then notes the particular dis instruction currently
67*46439007SCharles.Forsythbeing executed before repeating the process. After many such samples, an accurate profile can be obtained.
68*46439007SCharles.Forsyth.LP
69*46439007SCharles.ForsythAt it's simplest we can profile a particular command by giving the command
70*46439007SCharles.Forsythto execute followed by any arguments to the command eg
71*46439007SCharles.Forsyth.sp
72*46439007SCharles.Forsyth.RS
73*46439007SCharles.Forsyth	prof wm/polyhedra
74*46439007SCharles.Forsyth.RE
75*46439007SCharles.Forsyth.sp
76*46439007SCharles.Forsythprofiles the polyhedra displayer. After letting the latter run for a reasonable
77*46439007SCharles.Forsythamount of time, we exit and then get the following statistics.
78*46439007SCharles.Forsyth.br
79*46439007SCharles.Forsyth.DS
80*46439007SCharles.ForsythModule: Wmlib(/dis/lib/wmlib.dis)
81*46439007SCharles.Forsyth
82*46439007SCharles.Forsyth34	0.06		str = load String String->PATH;
83*46439007SCharles.Forsyth
84*46439007SCharles.Forsyth**** module sampling points 1 ****
85*46439007SCharles.Forsyth
86*46439007SCharles.Forsyth.DE
87*46439007SCharles.Forsyth.DS
88*46439007SCharles.ForsythModule: Bufio(/dis/lib/bufio.dis)
89*46439007SCharles.Forsyth
90*46439007SCharles.Forsyth340	0.06			n := 0;
91*46439007SCharles.Forsyth341	0.12			while(b.index < b.size){
92*46439007SCharles.Forsyth342	0.99				(ch, i, nil) = sys->byte2char(b.buffer[0:b.size], b.index);
93*46439007SCharles.Forsyth
94*46439007SCharles.Forsyth**** module sampling points 19 ****
95*46439007SCharles.Forsyth
96*46439007SCharles.ForsythModule: Polyfill(/dis/math/polyfill.dis)
97*46439007SCharles.Forsyth
98*46439007SCharles.Forsyth37	10.80		for(i := 0; i < n; i++)
99*46439007SCharles.Forsyth38	19.86			b0[i] = b1[i] = ∞;
100*46439007SCharles.Forsyth57	0.06		p.y += y;
101*46439007SCharles.Forsyth58	1.18		dst.line((left, y), (right, y), Endsquare, Endsquare, 0, src, p);
102*46439007SCharles.Forsyth63	0.12		prevx := ∞;
103*46439007SCharles.Forsyth64	9.93		for(x := left; x <= right; x++){
104*46439007SCharles.Forsyth65	20.61			if(z+e < zbuf0[k] || (z-e <= zbuf1[k] && x != right && prevx != ∞)){
105*46439007SCharles.Forsyth66	6.46				zbuf0[k] = z-e;
106*46439007SCharles.Forsyth67	5.71				zbuf1[k] = z+e;
107*46439007SCharles.Forsyth68	0.74				if(prevx == ∞)
108*46439007SCharles.Forsyth69	0.74					prevx = x;
109*46439007SCharles.Forsyth71	0.12			else if(prevx != ∞){
110*46439007SCharles.Forsyth72	0.25				fillline(dst, prevx, x-1, y, src, p);
111*46439007SCharles.Forsyth73	2.61				prevx = ∞;
112*46439007SCharles.Forsyth75	4.35			z += dx;
113*46439007SCharles.Forsyth76	3.17			k++;
114*46439007SCharles.Forsyth78	0.06		if(prevx != ∞)
115*46439007SCharles.Forsyth79	0.87			fillline(dst, prevx, right, y, src, p);
116*46439007SCharles.Forsyth80	0.06	}
117*46439007SCharles.Forsyth152	0.06			return (vx/z, mod);
118*46439007SCharles.Forsyth186	0.06			sp.dzrem = mod(sp.num, sp.den) << fixshift;
119*46439007SCharles.Forsyth187	0.06			sp.dz += sdiv(sp.dzrem, sp.den);
120*46439007SCharles.Forsyth217	0.62			for(q = p = 0; p < ep; p++) {
121*46439007SCharles.Forsyth218	0.37				sp = seg[p];
122*46439007SCharles.Forsyth220	0.12					continue;
123*46439007SCharles.Forsyth221	0.12				sp.z += sp.dz;
124*46439007SCharles.Forsyth222	0.19				sp.zerr += sp.dzrem;
125*46439007SCharles.Forsyth223	0.12				if(sp.zerr >= sp.den) {
126*46439007SCharles.Forsyth224	0.19					sp.z++;
127*46439007SCharles.Forsyth225	0.25					sp.zerr -= sp.den;
128*46439007SCharles.Forsyth226	0.25					if(sp.zerr < 0 || sp.zerr >= sp.den)
129*46439007SCharles.Forsyth227	0.25						sys->print("bad ratzerr1: %d den %d dzrem %d\n", sp.zerr, sp.den, sp.dzrem);
130*46439007SCharles.Forsyth229	0.31				seg[q] = sp;
131*46439007SCharles.Forsyth230	0.31				q++;
132*46439007SCharles.Forsyth233	0.25			for(p = next; seg[p] != nil; p++) {
133*46439007SCharles.Forsyth234	0.06				sp = seg[p];
134*46439007SCharles.Forsyth247	0.12			ep = q;
135*46439007SCharles.Forsyth248	0.06			next = p;
136*46439007SCharles.Forsyth257	0.06				continue;
137*46439007SCharles.Forsyth260	0.62			zsort(seg, ep);
138*46439007SCharles.Forsyth262	0.25			for(p = 0; p < ep; p++) {
139*46439007SCharles.Forsyth263	0.19				sp = seg[p];
140*46439007SCharles.Forsyth264	0.06				cnt = 0;
141*46439007SCharles.Forsyth265	0.06				x = sp.z;
142*46439007SCharles.Forsyth266	0.25				ix = (x + onehalf) >> fixshift;
143*46439007SCharles.Forsyth267	0.06				if(ix >= maxx)
144*46439007SCharles.Forsyth271	0.06				cnt += sp.d;
145*46439007SCharles.Forsyth272	0.12				p++;
146*46439007SCharles.Forsyth273	0.25				sp = seg[p];
147*46439007SCharles.Forsyth275	0.06					if(p == ep) {
148*46439007SCharles.Forsyth277	0.06						return;
149*46439007SCharles.Forsyth279	0.06					cnt += sp.d;
150*46439007SCharles.Forsyth280	0.12					if((cnt&wind) == 0)
151*46439007SCharles.Forsyth283	0.19					sp = seg[p];
152*46439007SCharles.Forsyth286	0.25				ix2 = (x2 + onehalf) >> fixshift;
153*46439007SCharles.Forsyth291	1.92				filllinez(dst, ix, ix2, iy, zv+ix*dx, er, dx, k+ix-zr.min.x, zbuf0, zbuf1, src, spt);
154*46439007SCharles.Forsyth293	0.06			y += (1<<fixshift);
155*46439007SCharles.Forsyth294	0.31			iy++;
156*46439007SCharles.Forsyth295	0.06			k += xlen;
157*46439007SCharles.Forsyth296	0.06			zv += dy;
158*46439007SCharles.Forsyth298	0.06	}
159*46439007SCharles.Forsyth310	0.06				done = 1;
160*46439007SCharles.Forsyth311	0.12				q--;
161*46439007SCharles.Forsyth312	0.25				for(p = 0; p < q; p++) {
162*46439007SCharles.Forsyth313	0.87					if(seg[p].z > seg[p+1].z) {
163*46439007SCharles.Forsyth367	0.06			t = a[0]; a[0] = a[i]; a[i] = t;
164*46439007SCharles.Forsyth373	0.06				while(i < n && ycompare(a[i], a[0]) < 0);
165*46439007SCharles.Forsyth379	0.12				t = a[i]; a[i] = a[j]; a[j] = t;
166*46439007SCharles.Forsyth384	0.06				qsortycompare(a, j);
167*46439007SCharles.Forsyth
168*46439007SCharles.Forsyth**** module sampling points 1584 ****
169*46439007SCharles.Forsyth
170*46439007SCharles.ForsythModule: Polyhedra(/dis/wm/polyhedra.dis)
171*46439007SCharles.Forsyth
172*46439007SCharles.Forsyth327	0.12		return (int (geo.sx*v.x)+geo.tx, int (geo.sy*v.y)+geo.ty);
173*46439007SCharles.Forsyth471	0.06					if(allf || dot(geo.view, newn[j]) < 0.0)
174*46439007SCharles.Forsyth472	0.06						polyfilla(fv[j], new, newn[j], dot(geo.light, newn[j]), geo, concave, inc);
175*46439007SCharles.Forsyth496	0.06			ap[j] = map(vtx, geo);
176*46439007SCharles.Forsyth512	0.06			if(a <= -LIMIT || a >= LIMIT)
177*46439007SCharles.Forsyth531	0.06			fillpoly(RDisp, ap, ~0, face, (0, 0), geo.zstate, dc, dx, dy);
178*46439007SCharles.Forsyth
179*46439007SCharles.Forsyth**** module sampling points 7 ****
180*46439007SCharles.Forsyth
181*46439007SCharles.Forsyth
182*46439007SCharles.Forsyth**** total sampling points 1611 ****
183*46439007SCharles.Forsyth.DE
184*46439007SCharles.Forsyth.br
185*46439007SCharles.ForsythThe output lists all lines in all modules with a sampling point. Each line
186*46439007SCharles.Forsythshows the line number in the corresponding source file, the percentage of
187*46439007SCharles.Forsythtime spent on that line and the source code. We can see that about 60% of
188*46439007SCharles.Forsyththe sampling points occur on lines 37, 38, 64 and 65 of the Polyfill module.
189*46439007SCharles.ForsythWith this information we might then try to speed up this part of the code
190*46439007SCharles.Forsythby altering the algorithm or making the limbo code more efficient (for
191*46439007SCharles.Forsythinstance by moving constant calculations or addressing out of loops).
192*46439007SCharles.Forsyth.LP
193*46439007SCharles.ForsythThe number of sampling points is also shown. The sampling rate can be
194*46439007SCharles.Forsythincreased with the -s option to give better granularity.
195*46439007SCharles.ForsythThis will cause a decrease in apparent performance but increases the
196*46439007SCharles.Forsythaccuracy of the results. The above example showed the results for all
197*46439007SCharles.Forsythmodules sampled. We might have restricted attention to the two main
198*46439007SCharles.Forsythpolyhedra modules instead by executing
199*46439007SCharles.Forsyth.sp
200*46439007SCharles.Forsyth.RS
201*46439007SCharles.Forsyth	prof -m Polyhedra -m Polyfill wm/polyhedra
202*46439007SCharles.Forsyth.RE
203*46439007SCharles.Forsyth.sp
204*46439007SCharles.ForsythSee the manual page for other options to
205*46439007SCharles.Forsyth.I prof
206*46439007SCharles.Forsythand further examples.
207*46439007SCharles.Forsyth.NH1
208*46439007SCharles.ForsythCprof
209*46439007SCharles.Forsyth.LP
210*46439007SCharles.ForsythCoverage of instructions is achieved by running a special dis instruction execute routine in place of the usual one (just as the debugger does).
211*46439007SCharles.ForsythThis routine notes down each
212*46439007SCharles.Forsythinstruction as it is executed. The profile device then passes this information
213*46439007SCharles.Forsythto
214*46439007SCharles.Forsyth.I cprof
215*46439007SCharles.Forsythvia the io system.
216*46439007SCharles.Forsyth.LP
217*46439007SCharles.ForsythThe coverage profiler is used in a similar way to the time profiler.
218*46439007SCharles.Forsyth.sp
219*46439007SCharles.Forsyth.RS
220*46439007SCharles.Forsyth	cprof -m Zeros zeros 1024 2880
221*46439007SCharles.Forsyth.RE
222*46439007SCharles.Forsyth.sp
223*46439007SCharles.Forsythgives
224*46439007SCharles.Forsyth.br
225*46439007SCharles.Forsyth.DS
226*46439007SCharles.ForsythModule: Zeros(zeros.dis)	56% coverage
227*46439007SCharles.Forsyth
228*46439007SCharles.Forsyth1	 	implement Zeros;
229*46439007SCharles.Forsyth2
230*46439007SCharles.Forsyth3	 	include "sys.m";
231*46439007SCharles.Forsyth4	 		sys: Sys;
232*46439007SCharles.Forsyth5	 	include "arg.m";
233*46439007SCharles.Forsyth6	 		arg: Arg;
234*46439007SCharles.Forsyth7	 	include "string.m";
235*46439007SCharles.Forsyth8	 		str: String;
236*46439007SCharles.Forsyth9	 	include "keyring.m";
237*46439007SCharles.Forsyth10	 	include "security.m";
238*46439007SCharles.Forsyth11	 		random: Random;
239*46439007SCharles.Forsyth12
240*46439007SCharles.Forsyth13	 	include "draw.m";
241*46439007SCharles.Forsyth14
242*46439007SCharles.Forsyth15	 	Zeros: module
243*46439007SCharles.Forsyth16	 	{
244*46439007SCharles.Forsyth17	 		init: fn(nil: ref Draw->Context, argv: list of string);
245*46439007SCharles.Forsyth18	 	};
246*46439007SCharles.Forsyth19
247*46439007SCharles.Forsyth20	 	init(nil: ref Draw->Context, argv: list of string)
248*46439007SCharles.Forsyth21	 	{
249*46439007SCharles.Forsyth22	 		z: array of byte;
250*46439007SCharles.Forsyth23	 		i: int;
251*46439007SCharles.Forsyth24	+		sys = load Sys Sys->PATH;
252*46439007SCharles.Forsyth25	+		arg = load Arg Arg->PATH;
253*46439007SCharles.Forsyth26	+		str = load String String->PATH;
254*46439007SCharles.Forsyth27
255*46439007SCharles.Forsyth28	+		if(sys == nil || arg == nil)
256*46439007SCharles.Forsyth29	-			return;
257*46439007SCharles.Forsyth30
258*46439007SCharles.Forsyth31	+		bs := 0;
259*46439007SCharles.Forsyth32	+		n := 0;
260*46439007SCharles.Forsyth33	+		val := 0;
261*46439007SCharles.Forsyth34	+		rflag := 0;
262*46439007SCharles.Forsyth35	+		arg->init(argv);
263*46439007SCharles.Forsyth36	+		while ((c := arg->opt()) != 0)
264*46439007SCharles.Forsyth37	-			case c {
265*46439007SCharles.Forsyth38	-			'r' => rflag = 1;
266*46439007SCharles.Forsyth39	-			'v' => (val, nil) = str->toint(arg->arg(), 16);
267*46439007SCharles.Forsyth40	-			* => sys->raise(sys->sprint("fail: unknown option (%c)\n", c));
268*46439007SCharles.Forsyth41	 			}
269*46439007SCharles.Forsyth.DE
270*46439007SCharles.Forsyth.DS
271*46439007SCharles.Forsyth42	+		argv = arg->argv();
272*46439007SCharles.Forsyth43	+		if(len argv >= 1)
273*46439007SCharles.Forsyth44	+			bs = int hd argv;
274*46439007SCharles.Forsyth45	 		else
275*46439007SCharles.Forsyth46	-			bs = 1;
276*46439007SCharles.Forsyth47	+		if (len argv >= 2)
277*46439007SCharles.Forsyth48	+			n = int hd tl argv;
278*46439007SCharles.Forsyth49	 		else
279*46439007SCharles.Forsyth50	-			n = 1;
280*46439007SCharles.Forsyth51	+		if(bs == 0 || n == 0) {
281*46439007SCharles.Forsyth52	-			sys->fprint(sys->fildes(2), "usage: zeros [-r] [-v value] blocksize [number]\n");
282*46439007SCharles.Forsyth53	-			sys->raise("fail: usage");
283*46439007SCharles.Forsyth54	 		}
284*46439007SCharles.Forsyth55	+		if (rflag) {
285*46439007SCharles.Forsyth56	-			random = load Random Random->PATH;
286*46439007SCharles.Forsyth57	-			if (random == nil)
287*46439007SCharles.Forsyth58	-				sys->raise("fail: no security module\n");
288*46439007SCharles.Forsyth59	-			z = random->randombuf(random->NotQuiteRandom, bs);
289*46439007SCharles.Forsyth60	 		}
290*46439007SCharles.Forsyth61	 		else {
291*46439007SCharles.Forsyth62	+			z = array[bs] of byte;
292*46439007SCharles.Forsyth63	+			for(i=0;i<bs;i++)
293*46439007SCharles.Forsyth64	+				z[i] = byte val;
294*46439007SCharles.Forsyth65	 		}
295*46439007SCharles.Forsyth66	+		for(i=0;i<n;i++)
296*46439007SCharles.Forsyth67	+			sys->write(sys->fildes(1), z, bs);
297*46439007SCharles.Forsyth68	+	}
298*46439007SCharles.Forsyth
299*46439007SCharles.Forsyth**** module dis instructions 39725 ****
300*46439007SCharles.Forsyth.DE
301*46439007SCharles.Forsyth.br
302*46439007SCharles.ForsythHere the -m option has restricted attention to the Zeros module itself.
303*46439007SCharles.ForsythThe output shows the source line number, an indicator of coverage and
304*46439007SCharles.Forsyththe source. The indicator is + if the line has been executed, - if
305*46439007SCharles.Forsythit hasn't and ? if only part of it has (for instance a loop statement that has
306*46439007SCharles.Forsythnever had it's iteration part executed). Lines with no indicator have no
307*46439007SCharles.Forsythcorresponding dis instructions associated with them. Another option (-f)
308*46439007SCharles.Forsythshows coverage frequencies instead.
309*46439007SCharles.Forsyth.LP
310*46439007SCharles.ForsythAn alternative to
311*46439007SCharles.Forsyth.I cprof
312*46439007SCharles.Forsythis
313*46439007SCharles.Forsyth.I wm/cprof
314*46439007SCharles.Forsythwhich shows the statistics graphically.
315*46439007SCharles.ForsythIt's options are pretty much the same as those to
316*46439007SCharles.Forsyth.I cprof .
317*46439007SCharles.ForsythUnexecuted and
318*46439007SCharles.Forsythpartially executed lines of code are shown in colour. See the man page
319*46439007SCharles.Forsythfor exact details of the colouring convention
320*46439007SCharles.Forsyth.LP
321*46439007SCharles.ForsythResults may be accumulated with the -r option so that multiple runs of
322*46439007SCharles.Forsythcode can be made. The resulting statistics go into a file <xxx>.prf when
323*46439007SCharles.Forsyth<xxx>.dis is the corresponding dis file. See the manual page for further
324*46439007SCharles.Forsythdetails on how to use this option and then review the accumulated
325*46439007SCharles.Forsythresults.
326*46439007SCharles.Forsyth.NH 1
327*46439007SCharles.ForsythMprof
328*46439007SCharles.Forsyth.LP
329*46439007SCharles.ForsythWhen memory profiling, the kernel profile device associates each heap allocation with a line of limbo source and each heap deallocation with the line of
330*46439007SCharles.Forsythlimbo source that allocated it. In this way, current memory usage and
331*46439007SCharles.Forsythhigh-water usage can be determined on a line by line basis.
332*46439007SCharles.Forsyth.LP
333*46439007SCharles.ForsythHere it seems that memory usage at a particular point in the execution of
334*46439007SCharles.Forsytha program is more appropriate than the post-mortem approach of
335*46439007SCharles.Forsyth.I prof
336*46439007SCharles.Forsythand
337*46439007SCharles.Forsyth.I cprof
338*46439007SCharles.Forsyth, so an interactive example is described (though
339*46439007SCharles.Forsyth.I mprof
340*46439007SCharles.Forsythcan be
341*46439007SCharles.Forsythused non-interactively and
342*46439007SCharles.Forsyth.I prof
343*46439007SCharles.Forsythinteractively if so desired). See the manual
344*46439007SCharles.Forsythpages for complete details and further examples.
345*46439007SCharles.Forsyth.LP
346*46439007SCharles.ForsythTo do this we execute
347*46439007SCharles.Forsyth.sp
348*46439007SCharles.Forsyth.RS
349*46439007SCharles.Forsyth	mprof -b -m Polyhedra
350*46439007SCharles.Forsyth.RE
351*46439007SCharles.Forsyth.sp
352*46439007SCharles.Forsythwhich kicks off profiling and restricts attention to the Polyhedra module
353*46439007SCharles.Forsythwhenever it runs. The -b simply says begin profiling. Note that no command
354*46439007SCharles.Forsythto execute is given to
355*46439007SCharles.Forsyth.I mprof
356*46439007SCharles.Forsythat this stage. Then run the command
357*46439007SCharles.Forsyth.sp
358*46439007SCharles.Forsyth.RS
359*46439007SCharles.Forsyth	wm/polyhedra &
360*46439007SCharles.Forsyth.RE
361*46439007SCharles.Forsyth.sp
362*46439007SCharles.Forsythand interact with it. Now show memory statistics
363*46439007SCharles.Forsyth.sp
364*46439007SCharles.Forsyth.RS
365*46439007SCharles.Forsyth	mprof
366*46439007SCharles.Forsyth.RE
367*46439007SCharles.Forsyth.sp
368*46439007SCharles.ForsythThis gives
369*46439007SCharles.Forsyth.br
370*46439007SCharles.Forsyth.DS
371*46439007SCharles.ForsythModule: Polyhedra(/dis/wm/polyhedra.dis)
372*46439007SCharles.Forsyth
373*46439007SCharles.Forsyth44	100	100		sys = load Sys Sys->PATH;
374*46439007SCharles.Forsyth45	132	132		draw = load Draw Draw->PATH;
375*46439007SCharles.Forsyth46	68	68		tk = load Tk Tk->PATH;
376*46439007SCharles.Forsyth47	1788	1788		wmlib = load Wmlib Wmlib->PATH;
377*46439007SCharles.Forsyth48	232	232		bufio = load Bufio Bufio->PATH;
378*46439007SCharles.Forsyth49	68	68		math = load Math Math->PATH;
379*46439007SCharles.Forsyth50	204	204		rand = load Rand Rand->PATH;
380*46439007SCharles.Forsyth51	0	3504		daytime = load Daytime Daytime->PATH;
381*46439007SCharles.Forsyth52	544	544		polyfill = load Polyfill Polyfill->PATH;
382*46439007SCharles.Forsyth53	1824	1824		smenu = load Smenu Smenu->PATH;
383*46439007SCharles.Forsyth86	36	36		cmdch := chan of string;
384*46439007SCharles.Forsyth95	36	36		sync := chan of int;
385*46439007SCharles.Forsyth96	36	36		chanθ := chan of real;
386*46439007SCharles.Forsyth103	68	68		shade = array[NSHADES] of ref Image;
387*46439007SCharles.Forsyth116	36	36		yieldc := chan of int;
388*46439007SCharles.Forsyth120	36	36		sm := array[2] of ref Scrollmenu;
389*46439007SCharles.Forsyth378	68	176			s += " (" + string p.indx + ")";
390*46439007SCharles.Forsyth403	36	36		vec := array[2] of array of Vector;
391*46439007SCharles.Forsyth404	740	740		vec[0] = array[V] of Vector;
392*46439007SCharles.Forsyth405	740	740		vec[1] = array[V] of Vector;
393*46439007SCharles.Forsyth407	36	36			norm = array[2] of array of Vector;
394*46439007SCharles.Forsyth408	612	612			norm[0] = array[F] of Vector;
395*46439007SCharles.Forsyth409	612	612			norm[1] = array[F] of Vector;
396*46439007SCharles.Forsyth492	68	68		ap := array[n+1] of Point;
397*46439007SCharles.Forsyth609	164	164		geo := ref Geom;
398*46439007SCharles.Forsyth610	36	36		TM := array[4] of array of real;
399*46439007SCharles.Forsyth612	272	272			TM[i] = array[4] of real;
400*46439007SCharles.Forsyth663	8000	8000			p := ref Polyhedron;
401*46439007SCharles.Forsyth707	740	740		p.v = array[p.V] of Vector;
402*46439007SCharles.Forsyth710	612	612		p.f = array[p.F] of Vector;
403*46439007SCharles.Forsyth713	132	132		p.fv = array[p.F] of array of int;
404*46439007SCharles.Forsyth716	164	164		p.vf = array[p.V] of array of int;
405*46439007SCharles.Forsyth729	9504	9640			return s[0: len s - 1];
406*46439007SCharles.Forsyth750	3672	3672		a := array[n+2] of int;
407*46439007SCharles.Forsyth768	0	136				return (n, s[i+1:]);
408*46439007SCharles.Forsyth779	0	104				return (r, s[i+1:]);
409*46439007SCharles.Forsyth802	0	68			s = s[1:];
410*46439007SCharles.Forsyth806	0	72			s = s[0: ln-1];
411*46439007SCharles.Forsyth.DE
412*46439007SCharles.Forsyth.DS
413*46439007SCharles.Forsyth866	0	200		cmd(mainwin, ".f1.txt configure -text {" + s + "}");
414*46439007SCharles.Forsyth874	0	356		labs := array[n] of string;
415*46439007SCharles.Forsyth881	0	5128			labs[i++] = string q.indx + " " + name;
416*46439007SCharles.Forsyth884	0	68		cmd(top, mname + " configure -borderwidth 3");
417*46439007SCharles.Forsyth920	0	104			cmd(win, ". configure -height " + string (scrsize.y - bd * 2));
418*46439007SCharles.Forsyth934	0	244		cmd(win, ". configure -x " + string actr.min.x + " -y " + string actr.min.y);
419*46439007SCharles.Forsyth
420*46439007SCharles.ForsythModule totals	31416	33984
421*46439007SCharles.Forsyth.DE
422*46439007SCharles.Forsyth.br
423*46439007SCharles.ForsythWe get the source line number, the amount of memory in bytes
424*46439007SCharles.Forsythcurrently allocated on that line, the high-water mark in bytes and then the source. Thus
425*46439007SCharles.Forsythloading the Sys module on line 44 used 100 bytes and this memory is
426*46439007SCharles.Forsythstill allocated. Loading Daytime on line 51 used 3504 bytes but this is now
427*46439007SCharles.Forsythreleased (because the module pointer is set to nil in the source and the
428*46439007SCharles.Forsythmemory has been reclaimed). The string concatenation on line 378 currently uses 68 bytes
429*46439007SCharles.Forsythbut at it's worst it was 176 bytes.
430*46439007SCharles.Forsyth.LP
431*46439007SCharles.ForsythFurther interaction with wm/polyhedra can now be done and memory
432*46439007SCharles.Forsythstatistics reviewed before the
433*46439007SCharles.Forsythprofiling session is ended, throwing away the accumulated memory
434*46439007SCharles.Forsythstatistics inside the kernel with
435*46439007SCharles.Forsyth.sp
436*46439007SCharles.Forsyth.RS
437*46439007SCharles.Forsyth	mprof -c
438*46439007SCharles.Forsyth.RE
439*46439007SCharles.Forsyth.sp
440*46439007SCharles.ForsythThe -c option simply says cease profiling.
441*46439007SCharles.Forsyth.LP
442*46439007SCharles.ForsythAn alternative to
443*46439007SCharles.Forsyth.I mprof
444*46439007SCharles.Forsythis
445*46439007SCharles.Forsyth.I wm/mprof
446*46439007SCharles.Forsythwhich shows the statistics graphically.
447*46439007SCharles.ForsythIt's options are pretty much the same as those to
448*46439007SCharles.Forsyth.I mprof .
449*46439007SCharles.ForsythLines of code
450*46439007SCharles.Forsythwhich have allocated more of the memory are shown in darker shades of red.
451*46439007SCharles.Forsyth.NH 1
452*46439007SCharles.ForsythManual pages
453*46439007SCharles.Forsyth.LP
454*46439007SCharles.ForsythFurther information and other examples are given in the following
455*46439007SCharles.Forsythmanual pages :-
456*46439007SCharles.Forsyth.sp
457*46439007SCharles.Forsyth.RS
458*46439007SCharles.Forsyth.I cprof(1)
459*46439007SCharles.Forsyth.br
460*46439007SCharles.Forsyth.I mprof(1)
461*46439007SCharles.Forsyth.br
462*46439007SCharles.Forsyth.I prof(1)
463*46439007SCharles.Forsyth.br
464*46439007SCharles.Forsyth.I wm-cprof(1)
465*46439007SCharles.Forsyth.br
466*46439007SCharles.Forsyth.I wm-mprof(1)
467*46439007SCharles.Forsyth.RE
468*46439007SCharles.Forsyth.sp
469*46439007SCharles.ForsythFor the lower level library module interface to these profilers
470*46439007SCharles.Forsyth.sp
471*46439007SCharles.Forsyth.RS
472*46439007SCharles.Forsyth.I prof(2)
473*46439007SCharles.Forsyth.RE
474*46439007SCharles.Forsyth.sp
475*46439007SCharles.ForsythFor the kernel profile device which gathers timing, coverage and memory
476*46439007SCharles.Forsythstatistics
477*46439007SCharles.Forsyth.sp
478*46439007SCharles.Forsyth.RS
479*46439007SCharles.Forsyth.I prof(3)
480*46439007SCharles.Forsyth.RE
481*46439007SCharles.Forsyth.br
482*46439007SCharles.Forsyth.NH 1
483*46439007SCharles.ForsythSources
484*46439007SCharles.Forsyth.LP
485*46439007SCharles.ForsythThe relevant sources are
486*46439007SCharles.Forsyth.sp
487*46439007SCharles.Forsyth.RS
488*46439007SCharles.Forsyth.CW /module/profile.m
489*46439007SCharles.Forsyth.br
490*46439007SCharles.Forsyth.CW /appl/lib/profile.b
491*46439007SCharles.Forsyth.br
492*46439007SCharles.Forsyth.CW /appl/cmd/cprof.b
493*46439007SCharles.Forsyth.br
494*46439007SCharles.Forsyth.CW /appl/cmd/mprof.b
495*46439007SCharles.Forsyth.br
496*46439007SCharles.Forsyth.CW /appl/cmd/prof.b
497*46439007SCharles.Forsyth.br
498*46439007SCharles.Forsyth.CW /appl/wm/cprof.b
499*46439007SCharles.Forsyth.br
500*46439007SCharles.Forsyth.CW /appl/wm/mprof.b
501*46439007SCharles.Forsyth.br
502*46439007SCharles.Forsyth.CW /emu/devprof.c
503*46439007SCharles.Forsyth.br
504*46439007SCharles.Forsyth.CW /os/port/devprof.c
505*46439007SCharles.Forsyth.RE
506*46439007SCharles.Forsyth.NH 1
507*46439007SCharles.ForsythAddendum
508*46439007SCharles.Forsyth.LP
509*46439007SCharles.ForsythA gui version of
510*46439007SCharles.Forsyth.I prof
511*46439007SCharles.Forsythhas been added for completeness. See the manual page
512*46439007SCharles.Forsyth.I wm-prof(1)
513*46439007SCharles.Forsythand the source
514*46439007SCharles.Forsyth.CW /appl/wm/prof.b .
515