profiling
Matthew Fluet
Matthew Fluet <fluet@CS.Cornell.EDU>
Thu, 19 Apr 2001 11:12:34 -0400 (EDT)
> If you want to work on any of the other outstanding bugs (times, size,
> self-compile) feel free. I'm still a week or so from having any time.
I've reimplemented timing in the following way:
1. added struct rusage ru_gc to struct GC_State in gc.h
removed uint recentStart from struct GC_State in gc.h
2. modified gc.c to update ru_gc appropriately (i.e., perform
getrusage(RUSAGE_SELF, &ru_start) just before the gc, perform
getrusage(RUSAGE_SELF, &ru_finish) just after the gc,
and set ru_gc = ru_gc + (ru_finish - ru_start),
where I've defined appropriate rusagePlus and rusageMinus functions).
So, we now record all resource usage of the garbage collector, not just
time. The gcTime is still there and updated during a gc, but it will
(almost) always correspond to the time derived from the data in ru_gc.
(There might be some rounding cases where they will differ, but it
should be negligible; and we could avoid it by always resetting gcTime
to the time derived from ru_gc, rather than incrementing it with the
time derived from (ru_finish - ru_start).)
3. added /src/runtime/basis/MLton/rusage.c
The function MLton_RUsage_ru will atomically record the rusage for
SELF, CHILDREN and the GC as follows:
static struct rusage self;
static struct rusage children;
static struct rusage gc;
void MLton_RUsage_ru() {
gc = gcState.ru_gc;
getrusage(RUSAGE_SELF, &self);
getrusage(RUSAGE_CHILDREN, &children);
}
Then there are a series of accessors to pull the data out.
4. added /src/basis-library/mlton/rusage.{sig,sml}
signature MLTON_RUSAGE =
sig
type timeval = {sec: int, usec: int}
val toTime: timeval -> Time.time
type rusage = {utime: timeval, stime: timeval}
val rusage: unit -> {self: rusage, children: rusage, gc: rusage}
end
So, right now, I'm only pulling out the user and system time, but we
can easily add more accessors if we want other info. The
implementation of rusage is the obvious one: make the FFI call to
MLton_RUsage_ru and then run through the accessors.
Note that we don't need to worry about intervening GC calls any more.
Successive calls to MLton.RUsage.rusage will have self' >= self,
children' >= children, and gc' >= gc, and (self' - self) >= (gc' - gc).
5. modified /src/basis-library/mlton/mlton.{sig,sml} to have the RUsage
structure.
6. modified /src/lib/mlton/basic/time.{sig,sml} to use
MLton.RUsage.rusage. It converts the {sec usec} record into a
Time.time and will ditch any extra fields in the rusage that we might
add later
modified /src/lib/mlton/basic/{process,trace}.sml to use the new type
of Time.times
modified /src/mlton/control/control.sml to use the new type of
Time.times; in particular, we don't need pre and post versions any
more.
7. modified /src/basis-library/posix/proc-env.sml to revert
Posix.ProcEnv.times back to it's original definition.
8. modified /src/mlton/codegen/x86-codegen/x86-mlton.fun
to reflect change in offset of gcState.canHandle
And I think that's it. I'm running regressions and benchmarks now, and
I'll run a self-compile, regressions, and benchmarks tonight on a faster
machine. But, let me know if there are any objections/modifications to
the changes outlined above.