> 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; };