Re: [HACKERS] new heap manager mmalloc

From: jwieck(at)debis(dot)com (Jan Wieck)
To: tgl(at)sss(dot)pgh(dot)pa(dot)us (Tom Lane)
Cc: maillist(at)candle(dot)pha(dot)pa(dot)us, pgsql-hackers(at)postgreSQL(dot)org
Subject: Re: [HACKERS] new heap manager mmalloc
Date: 1999-01-29 14:02:26
Message-ID: m106EV8-000EBPC@orion.SAPserv.Hamburg.dsh.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Tom Lane wrote:

>
> Bruce Momjian <maillist(at)candle(dot)pha(dot)pa(dot)us> writes:
> > Actually, our problem is not malloc itself. Most Unix OS's have pretty
> > good malloc's, tuned to their OS. The problem is the number of times we
> > call it.
>
> [...]
>
> What we need to do is exploit the notion of pooled allocation
> (contexts), wherein the memory management apparatus doesn't keep track
> of each allocation individually, but just takes it from a pool of space
> that will all be freed at the same time. End of statement, end of
> transaction, etc, are good pool lifetimes for Postgres.
>
> We currently have the worst of both worlds: we pay malloc's overhead,
> and we have a *separate* bookkeeping layer on top of malloc that links
> allocated blocks together to allow everything to be freed at end-of-
> context. We should be able to do this more cheaply than malloc, not
> more expensively.

Right right right! Pooled allocation will gain performance
and the separate bookkeeping should be more useful.

I did some little hacking and placed a silly pool into
palloc() and friends. It simply uses bigger blocks of memory
for small allocations and keeps only a refcount in the block
to see when all allocations are pfree()'d. No chunks inside a
block are reused, instead it waits until the entire block is
free to throw it away (what doesn't happen as often as it
should). The blocks are allocated in the same memory context
the chunks should have been, so transaction ends
AllocSetReset() cleans them out anyway.

It is a poor, simple way to reduce the number of palloc()'d
segments, so it saves calls to malloc()/free() and reduces
the bookkeeping overhead in AllocSet...().

The performance win on the regression test is about 10%. So
it demonstrates that it's a good place for optimization.

For now, it noticably raises the memory consumption of the
backend. I think there are many small palloc()'d chunks not
free'd, that cause my entier blocks to stay in memory. And
since there is no reuse in a block, this summarizes up. This
kind of pool is useful for things that should stay until
transaction end.

But I can think of another thing that might help. A temporary
allocation pool stack.

The functions to manage it are:

void tmppalloc_push(void);
void tmppalloc_pop(void);
void *tmppalloc(Size size);
void *tmpuppalloc(Size size, int levels_up);

The stack does also handle the allocations in bigger blocks.
But no individual free's are necessary, because the closing
pop will throw away the innermost memory context. And since
there are no free and realloc functions, it must not remember
any information about the individual chunks. Could be a much
bigger win for all our little allocs (I've seen thousands of
2-16 byte allocations when hacking in the above - with the
old palloc(), every such has an additional overhead of 16
bytes in the AllocSet).

Well, it requires us to revise the entire backend code,
module per module, to look which palloc()'s could be changed
into temp ones. But we'll find MANY places where memory
isn't pfree()'d that nobody wants until transaction end.

Jan

--

#======================================================================#
# 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 Jan Wieck 1999-01-29 14:15:19 Re: [HACKERS] Postgres Speed or lack thereof
Previous Message Michael Meskes 1999-01-29 12:26:39 another ecpg patch