> The current design never shrinks the free header pools, and indeed there is
> probably little point in doing so, so nothing seems to be gained from
> including them in the collection process.
>
> Using my favourite 5000-generation life.pasm as an example:
> A total of 10930 collection runs were made
> Copying a total of 57801936 bytes
>
> Since the three pools occupy 1024 bytes each, 33576960 bytes of the above
> copying is due to the pools.
Allocating the pools from system memory would also help with the
GC_DEBUG-enabled parrot failing on startup, since we'd never be calling
Parrot_allocate during interpreter initialization (although we still do
call pmc_new, which could call dod, and/or perform allocations).
Below is a patch which allocates the pools from system memory.
Unfortunately, it doesn't seem to provide any noticeable speed gains. I
get anywhere from a -1 to 15 extra generations per second. Current results
show:
Old:
A total of 10930 collection runs were made
Copying a total of 57801936 bytes
New:
A total of 9999 collection runs were made
Copying a total of 27401216 bytes
System is a P3 1Ghz, 512MB ram, MSVC-compiled Parrot.
Mike Lambert
? life.pbc
Index: memory.c
===================================================================
RCS file: /cvs/public/parrot/memory.c,v
retrieving revision 1.30
diff -u -r1.30 memory.c
--- memory.c 29 Mar 2002 19:13:08 -0000 1.30
+++ memory.c 12 Apr 2002 09:15:59 -0000
@@ -110,31 +110,25 @@
/* Init the string header pool */
interpreter->arena_base->string_header_pool =
mem_sys_allocate(sizeof(struct free_pool));
- interpreter->arena_base->string_header_pool->pool_buffer.bufstart =
- Parrot_allocate(interpreter, 1024);
- interpreter->arena_base->string_header_pool->pool_buffer.flags =
- BUFFER_live_FLAG;
- interpreter->arena_base->string_header_pool->pool_buffer.buflen = 1024;
+ interpreter->arena_base->string_header_pool->bufstart =
+ mem_sys_allocate(1024);
+ interpreter->arena_base->string_header_pool->buflen = 1024;
interpreter->arena_base->string_header_pool->entries_in_pool = 0;
/* Init the buffer header pool */
interpreter->arena_base->buffer_header_pool =
mem_sys_allocate(sizeof(struct free_pool));
- interpreter->arena_base->buffer_header_pool->pool_buffer.bufstart =
- Parrot_allocate(interpreter, 1024);
- interpreter->arena_base->buffer_header_pool->pool_buffer.flags =
- BUFFER_live_FLAG;
- interpreter->arena_base->buffer_header_pool->pool_buffer.buflen = 1024;
+ interpreter->arena_base->buffer_header_pool->bufstart =
+ mem_sys_allocate(1024);
+ interpreter->arena_base->buffer_header_pool->buflen = 1024;
interpreter->arena_base->buffer_header_pool->entries_in_pool = 0;
/* Init the PMC header pool */
interpreter->arena_base->pmc_pool =
mem_sys_allocate(sizeof(struct free_pool));
- interpreter->arena_base->pmc_pool->pool_buffer.bufstart =
- Parrot_allocate(interpreter, 1024);
- interpreter->arena_base->pmc_pool->pool_buffer.flags =
- BUFFER_live_FLAG;
- interpreter->arena_base->pmc_pool->pool_buffer.buflen = 1024;
+ interpreter->arena_base->pmc_pool->bufstart =
+ mem_sys_allocate(1024);
+ interpreter->arena_base->pmc_pool->buflen = 1024;
interpreter->arena_base->pmc_pool->entries_in_pool = 0;
Parrot_new_pmc_header_arena(interpreter);
}
Index: resources.c
===================================================================
RCS file: /cvs/public/parrot/resources.c,v
retrieving revision 1.41
diff -u -r1.41 resources.c
--- resources.c 11 Apr 2002 18:54:33 -0000 1.41
+++ resources.c 12 Apr 2002 09:16:00 -0000
@@ -25,13 +25,12 @@
/* First, check and see if there's enough space in the free pool. If
we're within the size of a STRING pointer, we make it bigger */
if (pool->entries_in_pool * sizeof(PMC *) >=
- pool->pool_buffer.buflen - sizeof(PMC *)) {
+ pool->buflen - sizeof(PMC *)) {
/* If not, make the free pool bigger. We enlarge it by 20% */
- pool->pool_buffer.bufstart = mem_realloc(interpreter,
- pool->pool_buffer.bufstart,
- pool->pool_buffer.buflen,
- (UINTVAL)(pool->pool_buffer.buflen *
1.2));
- pool->pool_buffer.buflen = (UINTVAL)(pool->pool_buffer.buflen * 1.2);
+ pool->bufstart = mem_sys_realloc(pool->bufstart,
+ pool->buflen,
+ (UINTVAL)(pool->buflen * 1.2));
+ pool->buflen = (UINTVAL)(pool->buflen * 1.2);
}
#ifdef GC_DEBUG
@@ -40,7 +39,7 @@
/* Okay, so there's space. Add the header on */
((PMC *)to_add)->flags = PMC_on_free_list_FLAG;
- temp_ptr = pool->pool_buffer.bufstart;
+ temp_ptr = pool->bufstart;
temp_ptr += pool->entries_in_pool;
*temp_ptr = to_add;
pool->entries_in_pool++;
@@ -132,7 +131,7 @@
PMC **foo;
/* Set the pointer to the beginning of the pool */
foo =
- interpreter->arena_base->pmc_pool->pool_buffer.bufstart;
+ interpreter->arena_base->pmc_pool->bufstart;
/* Decrement the count of entries in the pool */
interpreter->arena_base->pmc_pool->entries_in_pool--;
/* Add the count of entries in the pool to the base
@@ -242,7 +241,7 @@
Buffer **foo;
/* Set the pointer to the beginning of the pool */
foo =
- interpreter->arena_base->buffer_header_pool->pool_buffer.bufstart;
+ interpreter->arena_base->buffer_header_pool->bufstart;
/* Decrement the count of entries in the pool */
interpreter->arena_base->buffer_header_pool->entries_in_pool--;
/* Add the count of entries in the pool to the base
@@ -283,13 +282,12 @@
/* First, check and see if there's enough space in the free pool. If
we're within the size of a STRING pointer, we make it bigger */
if (pool->entries_in_pool * sizeof(STRING *) >=
- pool->pool_buffer.buflen - sizeof(STRING *)) {
+ pool->buflen - sizeof(STRING *)) {
/* If not, make the free pool bigger. We enlarge it by 20% */
- pool->pool_buffer.bufstart = mem_realloc(interpreter,
- pool->pool_buffer.bufstart,
- pool->pool_buffer.buflen,
- (UINTVAL)(pool->pool_buffer.buflen *
1.2));
- pool->pool_buffer.buflen = (UINTVAL)(pool->pool_buffer.buflen * 1.2);
+ pool->bufstart = mem_sys_realloc(pool->bufstart,
+ pool->buflen,
+ (UINTVAL)(pool->buflen * 1.2));
+ pool->buflen = (UINTVAL)(pool->buflen * 1.2);
}
#ifdef GC_DEBUG
@@ -298,7 +296,7 @@
/* Okay, so there's space. Add the header on */
((Buffer *)to_add)->flags = BUFFER_on_free_list_FLAG;
- temp_ptr = pool->pool_buffer.bufstart;
+ temp_ptr = pool->bufstart;
temp_ptr += pool->entries_in_pool;
*temp_ptr = to_add;
pool->entries_in_pool++;
@@ -664,7 +662,7 @@
STRING **foo;
/* Set the pointer to the beginning of the pool */
foo =
- interpreter->arena_base->string_header_pool->pool_buffer.bufstart;
+ interpreter->arena_base->string_header_pool->bufstart;
/* Decrement the count of entries in the pool */
interpreter->arena_base->string_header_pool->entries_in_pool--;
/* Add the count of entries in the pool to the base
@@ -720,42 +718,6 @@
/* Start at the beginning */
cur_spot = new_block->start;
-
- /* First collect the free string header pool */
- memcpy(cur_spot,
- interpreter->arena_base->string_header_pool->pool_buffer.bufstart,
- interpreter->arena_base->string_header_pool->pool_buffer.buflen);
- interpreter->arena_base->string_header_pool->pool_buffer.bufstart = cur_spot;
- cur_size = interpreter->arena_base->string_header_pool->pool_buffer.buflen;
- if (cur_size & 0x0f) {
- cur_size &= ~0x0f;
- cur_size += 16;
- }
- cur_spot += cur_size;
-
- /* Collect the PMC header pool */
- memcpy(cur_spot,
- interpreter->arena_base->pmc_pool->pool_buffer.bufstart,
- interpreter->arena_base->pmc_pool->pool_buffer.buflen);
- interpreter->arena_base->pmc_pool->pool_buffer.bufstart = cur_spot;
- cur_size = interpreter->arena_base->pmc_pool->pool_buffer.buflen;
- if (cur_size & 0x0f) {
- cur_size &= ~0x0f;
- cur_size += 16;
- }
- cur_spot += cur_size;
-
- /* And the buffer header pool */
- memcpy(cur_spot,
- interpreter->arena_base->buffer_header_pool->pool_buffer.bufstart,
- interpreter->arena_base->buffer_header_pool->pool_buffer.buflen);
- interpreter->arena_base->buffer_header_pool->pool_buffer.bufstart = cur_spot;
- cur_size = interpreter->arena_base->buffer_header_pool->pool_buffer.buflen;
- if (cur_size & 0x0f) {
- cur_size &= ~0x0f;
- cur_size += 16;
- }
- cur_spot += cur_size;
/* Run through all the buffer header pools and copy */
for (cur_arena = interpreter->arena_base->last_STRING_Arena;
Index: examples/assembly/life.pasm
===================================================================
RCS file: /cvs/public/parrot/examples/assembly/life.pasm,v
retrieving revision 1.10
diff -u -r1.10 life.pasm
--- examples/assembly/life.pasm 19 Mar 2002 18:09:10 -0000 1.10
+++ examples/assembly/life.pasm 12 Apr 2002 09:16:01 -0000
@@ -5,7 +5,7 @@
# of life
#
# First the generation count
- set I2, 500
+ set I2, 5000
# Note the time
time N5
# If true, we don't print
Index: include/parrot/resources.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/resources.h,v
retrieving revision 1.25
diff -u -r1.25 resources.h
--- include/parrot/resources.h 18 Mar 2002 22:09:10 -0000 1.25
+++ include/parrot/resources.h 12 Apr 2002 09:16:01 -0000
@@ -70,7 +70,8 @@
/* The free header pool */
struct free_pool {
- Buffer pool_buffer;
+ void *bufstart;
+ UINTVAL buflen;
size_t entries_in_pool;
};