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