Re: [HACKERS] Postgres Speed or lack thereof

From: jwieck(at)debis(dot)com (Jan Wieck)
To: jwieck(at)debis(dot)com
Cc: tgl(at)sss(dot)pgh(dot)pa(dot)us, hackers(at)postgreSQL(dot)org
Subject: Re: [HACKERS] Postgres Speed or lack thereof
Date: 1999-02-02 14:35:30
Message-ID: m107gvK-000EBPC@orion.SAPserv.Hamburg.dsh.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

I wrote:

>
> I came to the same conclusion. So I continued with the
> approach of bigger chunks handled in palloc(). What I have
> now is something, that gains about 10% speedup at the
> regression test, while memory consumption (visibly watched
> with top(1)) seems not to raise compared against old version.
>
> Since the bigger blocks are built on top of the existing
> memory context model, it would not conflict with any enhanced
> usage we could make with it.
>
> I include a patch at the end - please comment.
>
>
> Jan

Did anyone play around with it? I've had it installed now for
some days and it work's well so far.

How close are we to v6.5 BETA? Should I apply it to CURRENT?

> diff -cr src.orig/backend/utils/mmgr/mcxt.c src/backend/utils/mmgr/mcxt.c
> *** src.orig/backend/utils/mmgr/mcxt.c Thu Jan 28 16:47:39 1999
> --- src/backend/utils/mmgr/mcxt.c Fri Jan 29 20:15:41 1999
> ***************
> *** 106,111 ****
> --- 106,112 ----
> static struct GlobalMemory TopGlobalMemoryData = {
> T_GlobalMemory, /* NodeTag tag */
> &GlobalContextMethodsData, /* ContextMethods method */
> + NULL, /* char* smallchunk_block */
> {{0}}, /* uninitialized OrderedSetData allocSetD */
> "TopGlobal", /* char* name */
> {0} /* uninitialized OrderedElemData elemD */
> diff -cr src.orig/backend/utils/mmgr/palloc.c src/backend/utils/mmgr/palloc.c
> *** src.orig/backend/utils/mmgr/palloc.c Thu Jan 28 16:47:39 1999
> --- src/backend/utils/mmgr/palloc.c Fri Jan 29 21:57:06 1999
> ***************
> *** 24,29 ****
> --- 24,57 ----
>
> #include "utils/palloc.h"
>
> +
> + typedef struct PallocBlock {
> + MemoryContext mcxt;
> + int refcount;
> + char *unused_chunk;
> + char *freeptr;
> + char *endptr;
> + } PallocBlock;
> +
> + typedef struct PallocChunk {
> + PallocBlock *blk;
> + Size size;
> + } PallocChunk;
> +
> +
> + #define PALLOC_BLOCKSIZE \
> + (8192 - sizeof(OrderedElemData) - sizeof(Size))
> + #define PALLOC_CHUNK_LIMIT 512
> + #define PALLOC_SIZE_ALIGN(s) ((s + 15) & ~15)
> +
> + #define PALLOC_CHUNK_BLKPTR(c) (((PallocChunk *)(c))[-1].blk)
> + #define PALLOC_CHUNK_SIZE(c) (((PallocChunk *)(c))[-1].size)
> +
> + #define PALLOC_CHUNK_HDRSZ MAXALIGN(sizeof(PallocChunk))
> + #define PALLOC_BLOCK_HDRSZ MAXALIGN(sizeof(PallocBlock))
> +
> + #define PALLOC_FREESPACE(b) ((b)->endptr - (b)->freeptr)
> +
> /* ----------------------------------------------------------------
> * User library functions
> * ----------------------------------------------------------------
> ***************
> *** 66,72 ****
> #ifdef PALLOC_IS_MALLOC
> return malloc(size);
> #else
> ! return MemoryContextAlloc(CurrentMemoryContext, size);
> #endif /* PALLOC_IS_MALLOC */
> }
>
> --- 94,168 ----
> #ifdef PALLOC_IS_MALLOC
> return malloc(size);
> #else
> ! PallocBlock *block;
> ! char *chunk;
> ! Size asize = PALLOC_SIZE_ALIGN(size);
> !
> ! if (asize >= PALLOC_CHUNK_LIMIT)
> ! {
> ! chunk = (char *)MemoryContextAlloc(CurrentMemoryContext, size +
> ! PALLOC_CHUNK_HDRSZ);
> ! chunk += PALLOC_CHUNK_HDRSZ;
> ! PALLOC_CHUNK_BLKPTR(chunk) = NULL;
> ! return (void *)chunk;
> ! }
> !
> ! block = (PallocBlock *)(CurrentMemoryContext->smallchunk_block);
> !
> ! if (block != NULL && PALLOC_FREESPACE(block) < asize)
> ! {
> ! char *prev = NULL;
> ! Size chunk_size;
> !
> ! chunk = block->unused_chunk;
> ! while (chunk)
> ! {
> ! chunk_size = PALLOC_CHUNK_SIZE(chunk);
> ! if (asize == chunk_size)
> ! {
> ! if (prev == NULL)
> ! block->unused_chunk = (char *)PALLOC_CHUNK_BLKPTR(chunk);
> ! else
> ! PALLOC_CHUNK_BLKPTR(prev) = PALLOC_CHUNK_BLKPTR(chunk);
> !
> ! block->refcount++;
> ! PALLOC_CHUNK_BLKPTR(chunk) = block;
> ! /*
> ! PALLOC_CHUNK_SIZE(chunk) = size;
> ! */
> ! return (void *)chunk;
> ! }
> ! prev = chunk;
> ! chunk = (char *)PALLOC_CHUNK_BLKPTR(chunk);
> ! }
> !
> ! block = NULL;
> ! }
> !
> ! if (block == NULL)
> ! {
> ! block = (PallocBlock *)MemoryContextAlloc(CurrentMemoryContext,
> ! PALLOC_BLOCKSIZE);
> ! block->mcxt = CurrentMemoryContext;
> ! block->unused_chunk = NULL;
> ! block->refcount = 0;
> ! block->freeptr = ((char *)block) + PALLOC_BLOCK_HDRSZ +
> ! PALLOC_CHUNK_HDRSZ;
> ! block->endptr = ((char *)block) + PALLOC_BLOCKSIZE;
> !
> ! CurrentMemoryContext->smallchunk_block = (void *)block;
> ! }
> !
> ! chunk = block->freeptr;
> ! block->freeptr += PALLOC_CHUNK_HDRSZ + asize;
> ! block->refcount++;
> ! PALLOC_CHUNK_BLKPTR(chunk) = block;
> ! PALLOC_CHUNK_SIZE(chunk) = asize;
> !
> ! if (block->freeptr >= block->endptr)
> ! block->mcxt->smallchunk_block = NULL;
> !
> ! return (void *)chunk;
> #endif /* PALLOC_IS_MALLOC */
> }
>
> ***************
> *** 76,82 ****
> #ifdef PALLOC_IS_MALLOC
> free(pointer);
> #else
> ! MemoryContextFree(CurrentMemoryContext, pointer);
> #endif /* PALLOC_IS_MALLOC */
> }
>
> --- 172,202 ----
> #ifdef PALLOC_IS_MALLOC
> free(pointer);
> #else
> ! PallocBlock *block = PALLOC_CHUNK_BLKPTR(pointer);
> !
> ! if (block == NULL)
> ! {
> ! MemoryContextFree(CurrentMemoryContext, (char *)pointer - PALLOC_CHUNK_HDRSZ);
> ! return;
> ! }
> !
> ! PALLOC_CHUNK_BLKPTR(pointer) = (PallocBlock *)(block->unused_chunk);
> ! block->unused_chunk = (char *)pointer;
> !
> ! block->refcount--;
> ! if (block->refcount == 0)
> ! {
> ! if (block == (PallocBlock *)(block->mcxt->smallchunk_block))
> ! {
> ! block->freeptr = ((char *)block) + PALLOC_BLOCK_HDRSZ +
> ! PALLOC_CHUNK_HDRSZ;
> ! block->unused_chunk = NULL;
> ! }
> ! else
> ! {
> ! MemoryContextFree(block->mcxt, (void *)block);
> ! }
> ! }
> #endif /* PALLOC_IS_MALLOC */
> }
>
> ***************
> *** 100,106 ****
> #ifdef PALLOC_IS_MALLOC
> return realloc(pointer, size);
> #else
> ! return MemoryContextRealloc(CurrentMemoryContext, pointer, size);
> #endif
> }
>
> --- 220,248 ----
> #ifdef PALLOC_IS_MALLOC
> return realloc(pointer, size);
> #else
> ! PallocBlock *block = PALLOC_CHUNK_BLKPTR(pointer);
> ! char *new;
> ! Size tocopy;
> !
> ! if (block == NULL)
> ! {
> ! new = (char *)MemoryContextRealloc(CurrentMemoryContext,
> ! (char *)pointer - PALLOC_CHUNK_HDRSZ,
> ! size + PALLOC_CHUNK_HDRSZ);
> ! new += PALLOC_CHUNK_HDRSZ;
> ! PALLOC_CHUNK_BLKPTR(new) = NULL;
> ! return (void *)new;
> ! }
> ! else
> ! {
> ! new = palloc(size);
> !
> ! tocopy = PALLOC_CHUNK_SIZE(pointer) > size ?
> ! size : PALLOC_CHUNK_SIZE(pointer);
> ! memcpy(new, pointer, tocopy);
> ! pfree(pointer);
> ! return (void *)new;
> ! }
> #endif
> }
>
> ***************
> *** 117,119 ****
> --- 259,263 ----
>
> return nstr;
> }
> +
> +
> diff -cr src.orig/backend/utils/mmgr/portalmem.c src/backend/utils/mmgr/portalmem.c
> *** src.orig/backend/utils/mmgr/portalmem.c Thu Jan 28 16:47:39 1999
> --- src/backend/utils/mmgr/portalmem.c Fri Jan 29 20:15:41 1999
> ***************
> *** 390,395 ****
> --- 390,396 ----
> NodeSetTag((Node *) &portal->variable, T_PortalVariableMemory);
> AllocSetInit(&portal->variable.setData, DynamicAllocMode, (Size) 0);
> portal->variable.method = &PortalVariableContextMethodsData;
> + portal->variable.smallchunk_block = NULL;
>
> /*
> * initialize portal heap context
> ***************
> *** 399,404 ****
> --- 400,406 ----
> FixedStackInit(&portal->heap.stackData,
> offsetof(HeapMemoryBlockData, itemData));
> portal->heap.method = &PortalHeapContextMethodsData;
> + portal->heap.smallchunk_block = NULL;
>
> /*
> * set bogus portal name
> ***************
> *** 756,761 ****
> --- 758,764 ----
> NodeSetTag((Node *) &portal->variable, T_PortalVariableMemory);
> AllocSetInit(&portal->variable.setData, DynamicAllocMode, (Size) 0);
> portal->variable.method = &PortalVariableContextMethodsData;
> + portal->variable.smallchunk_block = NULL;
>
> /* initialize portal heap context */
> NodeSetTag((Node *) &portal->heap, T_PortalHeapMemory);
> ***************
> *** 763,768 ****
> --- 766,772 ----
> FixedStackInit(&portal->heap.stackData,
> offsetof(HeapMemoryBlockData, itemData));
> portal->heap.method = &PortalHeapContextMethodsData;
> + portal->heap.smallchunk_block = NULL;
>
> /* initialize portal name */
> length = 1 + strlen(name);
> ***************
> *** 918,923 ****
> --- 922,928 ----
>
> /* free current mode */
> AllocSetReset(&HEAPMEMBLOCK(context)->setData);
> + context->smallchunk_block = NULL;
> MemoryContextFree((MemoryContext) PortalHeapMemoryGetVariableMemory(context),
> context->block);
>
> diff -cr src.orig/include/nodes/memnodes.h src/include/nodes/memnodes.h
> *** src.orig/include/nodes/memnodes.h Thu Jan 28 16:47:39 1999
> --- src/include/nodes/memnodes.h Fri Jan 29 20:15:41 1999
> ***************
> *** 60,65 ****
> --- 60,66 ----
> {
> NodeTag type;
> MemoryContextMethods method;
> + void *smallchunk_block;
> } *MemoryContext;
>
> /* think about doing this right some time but we'll have explicit fields
> ***************
> *** 68,73 ****
> --- 69,75 ----
> {
> NodeTag type;
> MemoryContextMethods method;
> + void *smallchunk_block;
> AllocSetData setData;
> char *name;
> OrderedElemData elemData;
> ***************
> *** 79,84 ****
> --- 81,87 ----
> {
> NodeTag type;
> MemoryContextMethods method;
> + void *smallchunk_block;
> AllocSetData setData;
> } *PortalVariableMemory;
>
> ***************
> *** 86,91 ****
> --- 89,95 ----
> {
> NodeTag type;
> MemoryContextMethods method;
> + void *smallchunk_block;
> Pointer block;
> FixedStackData stackData;
> } *PortalHeapMemory;
>
>

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me. #
#======================================== jwieck(at)debis(dot)com (Jan Wieck) #

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Thomas G. Lockhart 1999-02-02 15:00:07 Re: [HACKERS] VACUUM ANALYZE failed on linux
Previous Message Tatsuo Ishii 1999-02-02 13:59:08 Re: [HACKERS] Backend problem with large objects