Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Annotation of /sml/trunk/src/compiler/MiscUtil/util/stats.sml
ViewVC logotype

Annotation of /sml/trunk/src/compiler/MiscUtil/util/stats.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 189 - (view) (download)

1 : monnier 16 (* stats.sml
2 :     *
3 :     * COPYRIGHT (c) 1994 AT&T Bell Laboratories.
4 :     *)
5 :    
6 :     signature STATS =
7 :     sig
8 :     type stat
9 : monnier 189 type counter
10 :    
11 :     (* The counters (argument) will be add'd whenever the new counter is *)
12 :     val newCounter : counter list -> counter
13 :     val getCounter : counter -> int
14 :     val addCounter : counter -> int -> unit
15 :    
16 :     (* A stat contains the sum of the argument counters. *)
17 :     val newStat : string * counter list -> stat
18 :     val getStat : stat -> int
19 :     (* Add the stat to the summary *)
20 :     val registerStat : stat -> unit
21 :    
22 :     (* old interface, deprecated. *)
23 : monnier 16 val makeStat : string -> stat
24 :     val addStat : stat -> int -> unit
25 :    
26 :     type phase
27 :     val makePhase : string -> phase
28 :     val doPhase : phase -> ('a -> 'b) -> ('a -> 'b)
29 :     val keepTime : bool ref
30 :     val approxTime : bool ref (* doesn't do anything right now *)
31 :     val sayBegin : bool ref
32 :     val sayEnd : bool ref
33 :     val summary : unit -> unit
34 :     val summarySp : unit -> unit
35 :     val reset : unit -> unit
36 :     end;
37 :    
38 :     structure Stats :> STATS =
39 :     struct
40 :    
41 :     structure T = Time
42 :    
43 :     val timeToStr = T.fmt 2
44 :    
45 : monnier 189 datatype counter = C of {c:int ref, cs:counter list}
46 :    
47 :     datatype stat = STAT of {name:string, tot: counter list}
48 : monnier 16 val allStats = ref (nil : stat list)
49 :    
50 :     fun lookSt(name,nil) = NONE
51 :     | lookSt(name,(p as STAT{name=n,...})::rest) =
52 :     if name=n then SOME p else lookSt(name,rest)
53 :    
54 :     fun insert(p as STAT{name=pn,...}, (q as STAT{name=qn,...})::rest) =
55 :     if pn<qn then p::q::rest else q::insert(p,rest)
56 :     | insert(p,nil) = p::nil
57 :    
58 : monnier 189 fun newCounter cs = C{c=ref 0, cs=cs}
59 :     fun addCounter (C{c,cs}) n = (c := !c + n; app (fn c => addCounter c n) cs)
60 :     fun getCounter (C{c=ref c,...}) = c
61 :    
62 :     fun newStat (name,cs) = STAT{name=name,tot=cs}
63 :     fun registerStat (p as STAT{name,tot}) =
64 :     (case lookSt (name,!allStats)
65 :     of SOME p => ()
66 :     | NONE => allStats := insert(p,!allStats))
67 :    
68 : monnier 16 fun makeStat name = (case lookSt (name,!allStats)
69 :     of SOME p => p
70 :     | NONE => let
71 : monnier 189 val p = newStat(name, [newCounter[]])
72 : monnier 16 in
73 :     allStats := insert(p,!allStats); p
74 :     end
75 :     (* end case *))
76 : monnier 189 fun addStat(STAT{tot=[c],...}) n = addCounter c n
77 : monnier 16
78 :     val say = Control.Print.say
79 :     val flush = Control.Print.flush
80 :    
81 :     (** NOTE: we should be able to rewrite this using the Timer structure **)
82 :     type times = {usr:T.time, sys:T.time, gc:T.time}
83 :     val zeros = {usr=T.zeroTime, sys=T.zeroTime, gc=T.zeroTime}
84 :    
85 :     datatype phase = PHASE of {name : string, accum : times ref, this: times ref}
86 :    
87 :     fun lookPh(name,nil) = NONE
88 :     | lookPh(name,(p as PHASE{name=n,...})::rest) =
89 :     if name=n then SOME p else lookPh(name,rest)
90 :    
91 :     fun insert(p as PHASE{name=pn,...}, (q as PHASE{name=qn,...})::rest) =
92 :     if pn<qn then p::q::rest else q::insert(p,rest)
93 :     | insert(p,nil) = p::nil
94 :    
95 :    
96 :     val allPhases = ref (nil : phase list)
97 :    
98 :     fun makePhase name = (case lookPh(name,!allPhases)
99 :     of SOME p => p
100 :     | NONE => let
101 :     val p = PHASE{name=name,accum=ref zeros, this=ref zeros}
102 :     in
103 :     allPhases := insert(p,!allPhases); p
104 :     end
105 :     (* end case *))
106 :    
107 :     val current = ref (makePhase "Other")
108 :    
109 :     val keepTime = ref true
110 :     val approxTime = ref true
111 :     val sayBegin = ref false
112 :     val sayEnd = ref false
113 :    
114 :     infix 6 ++ val op ++ = Time.+
115 :     infix 6 -- val op -- = Time.-
116 :    
117 :     infix 6 +++
118 :     fun {usr,sys,gc}+++{usr=u,sys=s,gc=g} = {usr=usr++u,sys=sys++s,gc=gc++g}
119 :     infix 6 ---
120 :     fun {usr,sys,gc}---{usr=u,sys=s,gc=g} =
121 :     if (Time.<(usr, u))
122 :     then zeros
123 :     else {usr=usr--u,sys=sys--s,gc=gc--g}
124 :    
125 :     local
126 :     fun gettime () = Timer.checkCPUTimer(Timer.totalCPUTimer())
127 :     val last = ref (gettime())
128 :     in
129 :     fun reset() = (
130 :     last := gettime();
131 :     app (fn PHASE{this,accum,...} => (this := zeros; accum := zeros))
132 :     (!allPhases);
133 : monnier 189 app (fn STAT{tot,...} => app (fn C{c,...} => c:=0) tot) (!allStats))
134 : monnier 16
135 :     structure CU = SMLofNJ.Internals.CleanUp
136 :     val _ = CU.addCleaner (
137 :     "CompilerStats",
138 :     [CU.AtExportML, CU.AtExportFn, CU.AtInit],
139 :     fn CU.AtInit => reset() | _ => last := zeros)
140 :    
141 :     fun since() = let
142 :     (***
143 :     val x = if !approxTime
144 :     then let
145 :     val t1 = !lastcollect
146 :     val u1 = !System.Runtime.minorcollections
147 :     in lastcollect := u1; u1<>t1 end
148 :     else true
149 :     ***)
150 :     val x = true
151 :     in
152 :     if x
153 :     then let
154 :     val t = !last
155 :     val u = gettime()
156 :     in last := u; (u --- t) end
157 :     else zeros
158 :     end
159 :     end (* local *)
160 :    
161 :     fun repeat 0 f x = () | repeat n f x= (f x; repeat (n-1) f x)
162 :     fun sayfield(n,s) = (say s; repeat (Int.max(0,n-size s)) say " ")
163 :    
164 :     fun doPhase (p as PHASE{name,this,accum}) f x = let
165 :     val prev as PHASE{this=t',...} = !current
166 :     fun endTime() = let
167 :     val x as {usr,sys,gc} = since() +++ !this
168 :     in
169 :     this := zeros;
170 :     accum := !accum +++ x;
171 :     usr++sys++gc
172 :     end
173 :     fun finish() = (
174 :     current := prev;
175 :     if !sayEnd
176 :     then (
177 :     say "End ";
178 :     sayfield(40,name);
179 :     if !keepTime
180 :     then app say [" ", timeToStr(endTime()), " sec\n"]
181 :     else say "\n";
182 :     flush())
183 :     else (endTime(); ()))
184 :     in
185 :     if !keepTime
186 :     then t' := since() +++ !t'
187 :     else ();
188 :     current := p;
189 :     if !sayBegin then (app say ["Begin ",name,"\n"]; flush()) else ();
190 :     (f x handle e => (finish(); raise e))
191 :     before finish()
192 :     end
193 :    
194 : monnier 189 fun getStat (STAT{tot,...}) = foldl (fn (c,s) => getCounter c + s) 0 tot
195 :     fun showStat(s as STAT{name,tot}) = (
196 : monnier 16 sayfield(40, name);
197 : monnier 189 say(Int.toString(getStat s));
198 : monnier 16 say "\n")
199 :    
200 :     fun showPhase(PHASE{name,this,accum}) = let
201 :     val {usr,sys,gc} = !this +++ !accum
202 :     in sayfield(40,name);
203 :     say(timeToStr usr); say "u ";
204 :     say(timeToStr sys); say "s ";
205 :     say(timeToStr gc); say "g ";
206 :     say "\n"
207 :     end
208 :    
209 :     fun summary() = let
210 :     val sum = foldr (fn(PHASE{accum,...},t)=> !accum+++t) zeros (!allPhases)
211 :     in
212 :     app showStat (!allStats);
213 :     app showPhase
214 :     (!allPhases @ [PHASE{name="TOTAL",this=ref zeros, accum=ref sum}])
215 :     end
216 :    
217 :     fun showPhaseSp(PHASE{name,this,accum}) = let
218 :     val {usr,sys,gc} = !this +++ !accum
219 :     in if (usr++sys++gc) = T.zeroTime then ()
220 :     else
221 :     (sayfield(40,name);
222 :     say(timeToStr (usr++sys)); say "u ";
223 :     (* say(timeToStr sys); say "s "; *)
224 :     say(timeToStr gc); say "g ";
225 :     say "\n")
226 :     end
227 :    
228 :     fun summarySp() = let
229 :     val sum = foldr (fn(PHASE{accum,...},t)=> !accum+++t) zeros (!allPhases)
230 :     in
231 :     app showStat (!allStats);
232 :     app showPhaseSp
233 :     (!allPhases @ [PHASE{name="TOTAL",this=ref zeros, accum=ref sum}])
234 :     end
235 :    
236 :     end (* structure Stats *)
237 :    
238 :     (*
239 : monnier 113 * $Log$
240 : monnier 16 *)

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0