"Mike Lambert" wrote:

> I know Dan's proposed solution has already been committed, but I'd
> like to add my support for this. In addition to providing a counter per
> opcode to ensure that we don't prematurely GC data, this field could also
> be reused to calculate the generation of a particular buffer, to help sort
> it into a correct generational pool (if/when we do get that).

I have almost convinced myself this is essential, due to the problem I am
currently fighting (the excessive memory usage in programs like zip and
quicksort - see below for more explanation).
Unfortunately, there is a fairly major performance impact (on my system,
anyway).
Perhaps a few volunteers could add the patch below and do before and after
mops, life, whatever benchmarks and post the results? This code just adds
the overhead of the cycle counter without any benefits.

The excess memory usage problem is caused partially because of the
decoupling of dead object detection and memory pool compaction. Some of the
recent changes have been aimed at improving performance by reducing the
frequency of DOD runs, since these are quite slow. However, we can then get
the situation where a large number of string allocations take place without
running out of free headers, so we never do a DOD run; compaction runs
therefore can't reclaim anything, because no strings have been declared dead
recently.
My preferred solution to this is to trigger DOD runs during memory
allocation, to see whether we can find reclaimable memory - this however
presents an infant mortality nightmare, which could be addressed using the
birthdate technique.
As an alternative to this, I am currently testing a scheme using flags, so
that the memory allocation system can request that a DOD run occur at the
next suitable opportunity, and possible vice versa.

> Another proposal is to walk the C stack. In runops (or some similar
This is more in line with standard GC systems, which have no option since
the program is assumed to be non-cooperative. It would probably require a
major rewrite of the memory manager, so, although it needs to considered, I
think it should become part of a separate project to design a next
generation memory management system from scratch, which can be plugged in
later - unless later has to be sooner to accomodate problems that can't be
resolved, albeit not optimally, in the current version.

--
Peter Gibbs
EmKel Systems

Index: include/parrot/interpreter.h
===================================================================
RCS file: /home/perlcvs/parrot/include/parrot/interpreter.h,v
retrieving revision 1.45
diff -u -r1.45 interpreter.h
--- include/parrot/interpreter.h        15 May 2002 07:25:37 -0000      1.45
+++ include/parrot/interpreter.h        26 May 2002 08:57:58 -0000
@@ -162,6 +162,7 @@
                                    requests are there? */
     UINTVAL GC_block_level;     /* How many outstanding GC block
                                    requests are there? */
+    UINTVAL cycle;              /* Opcode cycle counter */
 } Interp;

 #define PCONST(i) PF_CONST(interpreter->code, (i))
Index: lib/Parrot/OpsFile.pm
===================================================================
RCS file: /home/perlcvs/parrot/lib/Parrot/OpsFile.pm,v
retrieving revision 1.24
diff -u -r1.24 OpsFile.pm
--- lib/Parrot/OpsFile.pm       12 May 2002 18:57:43 -0000      1.24
+++ lib/Parrot/OpsFile.pm       26 May 2002 08:59:42 -0000
@@ -325,6 +325,9 @@

                     $body =~ s/\$(\d+)/{{\@$1}}/mg;

+# GC Experimental
+$body = "  interpreter->cycle++;\n{\n" . $body . "}";
+
       if ($ENV{PARROT_NO_LINE}) {
         $op->body($body);
       } else {



Reply via email to