Re: [HACKERS] Postgres Speed or lack thereof - Mailing list pgsql-hackers
From | jwieck@debis.com (Jan Wieck) |
---|---|
Subject | Re: [HACKERS] Postgres Speed or lack thereof |
Date | |
Msg-id | m107gvK-000EBPC@orion.SAPserv.Hamburg.dsh.de Whole thread Raw |
In response to | Re: [HACKERS] Postgres Speed or lack thereof (jwieck@debis.com (Jan Wieck)) |
Responses |
Re: [HACKERS] Postgres Speed or lack thereof
Re: [HACKERS] Postgres Speed or lack thereof Re: [HACKERS] Postgres Speed or lack thereof |
List | 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@debis.com (Jan Wieck) #
pgsql-hackers by date: