[mercury-users] What Triggers a GC?

Ralph Becket rbeck at microsoft.com
Fri Oct 22 03:19:28 AEST 1999


Back on this benchmarking thing...  I've getting fluctuating results.  At
one point (using rotd-08-13 I think) I was getting within a factor of
2.4 or so of the speed of the C implementation.  Now, using rotd-10-17,
I'm down to about 3.2, or 2.9 if I'm willing to turn GC off (which is
probably cheating).  Most odd.  A factor of three is *not bad at all*
though, chaps'n'chapesses.  [The nice thing is that the simple-then-
evolved version runs faster than the directish transliteration of the C].

Anyway, io__report_stats told me that 4 MBytes of heap had been used and
7 odd GCs had taken place.  This really is surprising to me because I've
gone to some lengths to make sure the code doesn't allocate any memory.  So
I popped the code through the profiler, trying to find where this memory is
going, but no dice - mprof agrees with me that nothing is being allocated
(and I've checked that I'm not using any of the mprof-invisible predicates
Fergus listed a couple of weeks ago).  So what causes a GC to take place?

Either way, I'm writing up the results now because I want to put this
project
to bed.  However, if any of the Mercury developers could spare a little time
to look over the code and see where the time is going, I'd be very
interested
to hear their conclusions (+ put names on the paper).  The code is only 130
lines or so of active source.

It seems to me that, for carefully written code, there shouldn't be *that*
much difference between what a C compiler and what the Mercury
(or any similar strict declarative language) compiler produce.  Looking at
the C produced by the Mercury compiler, there is an *awful* lot of register
rearranging going on and some inlining that one might expect doesn't seem
to be happening.  For example, a little bit of code like

set_code(Codes0, Hash, Key, Code) = Codes :-
        Codes1 = array__set(Codes0, Hash, Key),
        Codes  = array__set(Codes1, Hash + hash_table_size, Code).

which I would expect to compile to just a handful of instructions (with
array
bounds checking turned off), along the lines of

	  Codes0[Hash] = Key;
        Codes0[Hash + hash_table_size] = Code;
        Codes = Codes0;

but it actually compiles to

/* code for predicate 'set_code'/5 in mode 0 */
Define_static(mercury__fn__compress__set_code_4_0);
        MR_incr_sp_push_msg(3, "compress:set_code/5");
        MR_stackvar(3) = (Word) MR_succip;
        MR_stackvar(2) = r4;
        r4 = r3;
        r3 = r2;
        MR_stackvar(1) = r2;
        r2 = r1;
        r1 = (Word) (Word *) &mercury_data___type_ctor_info_int_0;
        call_localret(ENTRY(mercury__fn__array__set_3_0),
                mercury__fn__compress__set_code_4_0_i2,
                STATIC(mercury__fn__compress__set_code_4_0));
Define_label(mercury__fn__compress__set_code_4_0_i2);
 
update_prof_current_proc(LABEL(mercury__fn__compress__set_code_4_0));
        r2 = r1;
        r1 = (Word) (Word *) &mercury_data___type_ctor_info_int_0;
        r3 = ((Integer) MR_stackvar(1) + (Integer) 69001);
        r4 = MR_stackvar(2);
        MR_succip = (Code *) MR_stackvar(3);
        MR_decr_sp_pop_msg(3);
        tailcall(ENTRY(mercury__fn__array__set_3_0),
                STATIC(mercury__fn__compress__set_code_4_0));

and there's no sign of this being inlined.  It may just be me totally
misunderstanding what's going on/what is necessary, but I'd really like
to know.

Cheers,

Ralph
--------------------------------------------------------------------------
mercury-users mailing list
post:  mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the users mailing list