# New Ticket Created by  Mike Lambert 
# Please include the string:  [perl #15006]
# in the subject line of all future correspondence about this issue. 
# <URL: http://bugs6.perl.org/rt2/Ticket/Display.html?id=15006 >


This is a rather major refactoring of the GC code which I believe makes
the code much easier to follow and understand. It splits up resources.c
into smallobject.c, headers.c, dod.c, and resources.c.

BENCHMARKS:

Now, I know Dan wouldn't accept a refactoring patch to clarify code,
unless it had performance improvements. So here goes. :)

Using the benchmark .pasm's in the /examples/benchmarks/ directory, I
tested three different builds of parrot.
- orig: current version of parrot, as of wednesday morning
- orig+stackwalk: current version of parrot, with my stack-walking code
applied. This is slower than orig, but necessary for correct behavior. And
I didn't want the results to be skewed, comparing correct+fast versus
incorrect+slow.
- refactored+stackwalk: what this patch gives. lots of changes, some minor
tunings in terms of collection/dod logic, pool sizes, etc. And more
functionality.

The direct times, from summing three runs of each of /examples/benchmark,
gives: (smaller is better)

                               original   orig+stackwalk  refactored+stackwalk
gc_alloc_new.pbc               3.84       4.02            3.97
gc_alloc_reuse.pbc             12.66      12.63           9.46
gc_generations.pbc             4.09       5.92            6.07
gc_header_new.pbc              3.92       3.92            3.51
gc_header_reuse.pbc            4.23       5.85            5.76
gc_waves_headers.pbc           0.91       0.91            1.05
gc_waves_sizeable_data.pbc     7.51       7.55            7.30
gc_waves_sizeable_headers.pbc  5.43       5.56            6.11

Then scaling them against 'orig' as a baseline, I get: (smaller is better)

                               orig+stackwalk   refactored+stackwalk
gc_alloc_new.pbc               1.04             1.03
gc_alloc_reuse.pbc             1.00             0.75
gc_generations.pbc             1.45             1.49
gc_header_new.pbc              1.00             0.89
gc_header_reuse.pbc            1.38             1.36
gc_waves_headers.pbc           1.00             1.15
gc_waves_sizeable_data.pbc     1.01             0.97
gc_waves_sizeable_headers.pbc  1.02             1.13


Then summing these and re-scaling, we get:
orig:                 1.000
orig+stackwalk:       1.112
refactored+stackwalk: 1.096

Which puts this version a little ahead of the (correct) stackwalk version,
but behind the (incorrect) original version.

ROUGH OUTLINE:

smallobject.c contains the basic concept of allocation and management of
'small objects' (Creates large pools of identically-sized items.). It
requires manual allocation and deallocation, and thus is 'low-level'. The
various header systems are implemented on top of it, since they are
essentially small objects. keys could be implemented on top as well, but
it would require manual freeing (tradeoffs versus our current large KEY
structure with GC capabilities).

headers.c uses the smallobject code to provide the get_header,
free_header, etc code. Implements tracked (sized) headers, pmcs,
buffer/string headers, etc. I like the simplicity of this code,
personally. You create a header pool which provides a dod function, a free
function, a allocmore function, etc. PMCS and headers setup the functions
to call their own special functions and (un)initialize data when
necessary, layered on top of the underlying smallobject system. This is
where the (if any) speed loss is, since it uses function pointers instead
of direct function calls.  Everything else I've done is simply
reorganizing and moving code.

dod.c contains all of the dod code (doh!). Since these were seperate
stages from collection, I've moved them into different files for now, to
allow seperate tuning. In theory, one can modify resources.c (contains
collection stuff) to implement a generational system without modifying any
of the other files.

resources.c now contains collection, and the more ubiquitous resource
allocation functions for parrot. It's basically whatever didn't fit into
the above three files when I split up all the code. :)

Other changes that are different from the current system include storing
the alignment factor in the header pool, instead of making different
memory pools for them. This should improve memory usage, and reduce the
number of pools required.


STATUS:

It works. It compiles. It passes our meager GC tests. :)

I'm not sure what the plan is for 0.0.7 and TPC, but I've waited awhile
for the child collection problem to be fixed (stack walking was the
solution we adopted) so that this would work properly. As such, I can wait
until after TPC if this is deemed too radical when we're (are we?) trying
to get a stable build ready for TPC.

Melvin said he was "for" commiting this, so barring any objections from
the list, I think I'll let him do that. :) I'm sending it to the list
instead of him directly so that people can see the performance numbers
involved, and a rough outline of how things have changed, should you go
working on the GC stuff again. The above outline is more a 'diff' against
the old setup, than documentation.

This patch contains no less documentation (resources.c didn't have much
global description docs to begin with), so it's not any worse in that
department, but not much better. I believe the code to be more
self-documenting than before, since it's all in bite-sized chunks that are
easy to digest, but I know that's not a replacement for documentation. My
only real excuse is that I wrote the most of this pre-summer, when I still
had tuits, and I don't have the time anymore. FWIW, I do plan to work on
that aspect of the GC system when I get back into the swing of things this
fall, however.

Thanks for reading this far,
Mike Lambert



-- attachment  1 ------------------------------------------------------
url: http://bugs6.perl.org/rt2/attach/30021/25474/cd9524/latest.zip

Attachment: latest.zip
Description: latest.zip

Reply via email to