GC performance - was Re: [gclist] GC topics
David Chase
chase@centerline.com
Fri, 23 Feb 96 15:52:05 EST
> > float dist(coord * a, coord * b) {
> > float * bx = a -> x.mem;
> > float * ax = b -> x.mem;
> > int l = min (a -> x.len, b -> x.len) - 1;
> > int i;
> > float sum = 0;
> > float d1;
> >
> > /* Use some auto-increment addressing mode to
> > reference the arrays. */
> > for (i = 0; i <= l; i++) {
> > d1 = *ax - *bx;
> > ax++; bx++;
> > sum = sum + d1 * d1;
> > }
> >
> > return sqrt(sum); /* Should be tail-call optimized. */
> > }
> I suspect I'm missing something ... But, it would seem that the presence of
> a and b as arguments would guarantee the existence of pointers to a and b
> either within the stack or within the caller of dist. Or are compilers so
> clever that they can optimize away all the obvious references. (Apologies
> if this is discussed in your thesis).
It's not discussed as well as it ought to be, so no apologies are
necessary. However, at the machine level, bits are bits, and those
registers (on some machines, maybe not others) are completely eligible
for reuse. For instance, if this were a Sparc using the standard
calling conventions, one goal for a subroutine like this is to use
no more than 7 integer registers(*), thus avoiding the need to request
an additional register window. I think this is possible -- the lifetimes
that I see are:
a b bx ax t1 t2 l i (t1 and t2 are a,b -> x.len)
. . entry
. . . bx=
. . . . ax=
D . . . B a -> x.len
D . . . B b -> x.len
. . D D B min
. . . . rest of the code
(legend: B = birth, D = death, . = live at this point)
There's a total of 8 different "variables", and no particular reason
to prefer the parameters to any others. So, they can get overwritten,
once they are no longer needed. For different machines, you might
need a different example, but you get the idea.
(*) %o0-%o5, plus %g1. Certain compilation models also get you
%g2-%g4.
speaking for myself,
David Chase