Thread

  1. Re: [HACKERS] Postgres Speed or lack thereof

    Tom Lane <tgl@sss.pgh.pa.us> — 1999-01-24T19:54:52Z

    Vadim Mikheev <vadim@krs.ru> writes:
    > Tom Lane wrote:
    >> In other words, we're spending a third of our time mallocing and freeing
    >> memory.  A tad high, what?
    
    > I added some debug code to palloc/pfree and it shows that for
    > INSERT:
    > 1. 80% of allocations are made for <= 32 bytes.
    > 2. pfree is used for 25% of them only (others are freed
    >    after statement/transaction is done).
    
    I had suspected the former (because most of the allocs are
    parser nodes) and knew the latter from profile call counts.
    
    > Note that our mmgr adds 16 bytes to each allocation
    > (+ some bytes in malloc) - a great overhead, yes?
    
    Youch ... for a list-node-sized request, that's a lot of overhead.
    
    I did some more profiling this weekend, after Magnus Hagander and I
    repaired libpq's little problem with calling recv() once per input byte.
    Unsurprisingly, memory allocation is still 50% of backend CPU time in
    my test consisting of a long series of INSERT statements.  It's less
    than that, but still an interesting number, in two other test scenarios
    I set up:
    
    (1) SELECT the whole contents of a 6500-row, 38-column table; repeat 5 times.
        Memory allocation takes 8.74 of 54.45 backend CPU sec, or 16%.
    
    (2) Load a database from a pg_dump script.  Script size is 1.3MB.
        This is of course mostly CREATE TABLE, COPY from stdin, CREATE INDEX.
        Memory allocation takes 11.08 of 38.25 sec = 29%.
    
    I believe that the reason memory alloc is such a large percentage of the
    INSERT scenario is that this is the only one where lots of SQL parsing
    is going on.  In the SELECT scenario, most of the palloc/pfree traffic
    is temporary field value representations inside printtup (more about
    that below).  In the database load scenario, it seems that btree index
    building is the biggest hit; the heaviest callers of palloc are:
    
                    0.00    0.01   10642/438019      _bt_searchr [86]
                    0.00    0.01   13531/438019      heap_formtuple [149]
                    0.00    0.01   13656/438019      CopyFrom [24]
                    0.00    0.01   14196/438019      textin [247]
                    0.01    0.01   18275/438019      datetime_in [42]
                    0.01    0.03   32595/438019      bpcharin [182]
                    0.01    0.03   38882/438019      index_formtuple [79]
                    0.01    0.03   39028/438019      _bt_formitem [212]
                    0.07    0.16  204564/438019      _bt_setsortkey [78]
    [88]     1.3    0.14    0.34  438019         palloc [88]
    
    > I added code to allocate a few big (16K-64K) blocks of memory for
    > these small allocations to speed up palloc by skiping
    > AllocSetAlloc/malloc. New code don't free allocated memory (to make
    > bookkeeping fast) but keeping in mind 2. above and memory overhead it
    > seems as appropriate thing to do. These code also speed up freeing
    > when statement/transaction is done, because of only a few blocks have
    > to be freed now.
    
    This is pretty much what I had in mind, but I think that it is not OK
    to leave everything to be freed at statement end.  In particular I've
    just been looking at printtup(), the guts of SELECT output, and I see
    that each field value is palloc'd (by a type-specific output routine)
    and then pfree'd by printtup after emitting it.  If you make the pfrees
    all no-ops then this means the temporary space needed for SELECT is
    at least equal to the total volume of output data ... not good for
    huge tables.  (COPY in and out also seem to palloc/pfree each field
    value that goes past.)
    
    However, I think we could get around this by making more use of memory
    contexts.  The space allocated inside printtup could be palloc'd from a
    "temporary" context that gets flushed every so often (say, after every
    few hundred tuples of output).  All the pallocs done inside the parser
    could go to a "statement" context that is flushed at the end of each
    statement.  It'd probably also be a good idea to have two kinds of
    memory contexts, the current kind where each block is individually
    free-able and the new kind where we only keep track of how to free the
    whole context's contents at once.  That way, any particular routine that
    was going to allocate a *large* chunk of memory would have a way to free
    that chunk explicitly when done with it (but would have to remember
    which context it got it from in order to do the free).  For the typical
    list-node-sized request, we wouldn't bother with the extra bookkeeping.
    
    I think that palloc() could be defined as always giving you the bulk-
    allocated kind of chunk.  pfree() would become a no-op and eventually
    could be removed entirely.  Anyone who wants the other kind of chunk
    would call a different pair of routines, where the controlling memory
    context has to be named at both alloc and free time.  (This approach
    gets rid of your concern about the cost of finding which kind of context
    a block has been allocated in inside of pfree; we expect the caller
    to know that.)
    
    Getting this right is probably going to take some thought and work,
    but it looks worthwhile from a performance standpoint.  Maybe for 6.6?
    
    > It shows that we should get rid of system malloc/free and do
    > all things in mmgr itself - this would allow us much faster
    > free memory contexts at statement/transaction end.
    
    I don't think we can or should stop using malloc(), but we can
    ask it for large blocks and do our own allocations inside those
    blocks --- was that what you meant?
    
    			regards, tom lane
    
    
  2. Re: [HACKERS] Postgres Speed or lack thereof

    Goran Thyni <goran@kirra.net> — 1999-01-24T22:09:57Z

    Tom Lane wrote:
    > I don't think we can or should stop using malloc(), but we can
    > ask it for large blocks and do our own allocations inside those
    > blocks --- was that what you meant?
    
    I will just jump in with a small idea.
    The Gnome crowd is investigating using alloca instead of malloc/free
    where applicable. It is a huge save in CPU cycles where it can be used.
    
    	regards,
    -- 
    -----------------
    Göran Thyni
    This is Penguin Country. On a quiet night you can hear Windows NT
    reboot!
    
    
  3. Re: [HACKERS] Postgres Speed or lack thereof

    Marc Fournier <scrappy@hub.org> — 1999-01-24T22:26:45Z

    BUGS
         The alloca() function is machine dependent; its use is discouraged.
    
    
    On Sun, 24 Jan 1999, Goran Thyni wrote:
    
    > Tom Lane wrote:
    > > I don't think we can or should stop using malloc(), but we can
    > > ask it for large blocks and do our own allocations inside those
    > > blocks --- was that what you meant?
    > 
    > I will just jump in with a small idea.
    > The Gnome crowd is investigating using alloca instead of malloc/free
    > where applicable. It is a huge save in CPU cycles where it can be used.
    > 
    > 	regards,
    > -- 
    > -----------------
    > Gran Thyni
    > This is Penguin Country. On a quiet night you can hear Windows NT
    > reboot!
    > 
    
    Marc G. Fournier                                
    Systems Administrator @ hub.org 
    primary: scrappy@hub.org           secondary: scrappy@{freebsd|postgresql}.org 
    
    
    
  4. alloca (was: Postgres Speed or lack thereof)

    Goran Thyni <goran@kirra.net> — 1999-01-24T22:59:29Z

    The Hermit Hacker wrote:
    > BUGS
    >      The alloca() function is machine dependent; its use is discouraged.
    
    Gain a big potential speed boost, loose some portability.
    I think most modern unices has a good alloca, DOS and Mac
    don't, but who's porting the server there?
    
    Any unices out there missing alloca?
    
    	mvh,
    -- 
    -----------------
    Göran Thyni
    This is Penguin Country. On a quiet night you can hear Windows NT
    reboot!
    
    
  5. Re: [HACKERS] Postgres Speed or lack thereof

    Vadim Mikheev <vadim@krs.ru> — 1999-01-25T03:01:39Z

    Tom Lane wrote:
    > 
    > > Note that our mmgr adds 16 bytes to each allocation
    > > (+ some bytes in malloc) - a great overhead, yes?
    > 
    > Youch ... for a list-node-sized request, that's a lot of overhead.
    
    And lists are very often used by planner and - never pfreed.
    
    > Getting this right is probably going to take some thought and work,
    > but it looks worthwhile from a performance standpoint.  Maybe for 6.6?
    
    Yes - I have to return to MVCC stuff...
    So, I consider my exercizes with mmgr as vacation from MVCC -:)
    
    > > It shows that we should get rid of system malloc/free and do
    > > all things in mmgr itself - this would allow us much faster
    > > free memory contexts at statement/transaction end.
    > 
    > I don't think we can or should stop using malloc(), but we can
    > ask it for large blocks and do our own allocations inside those
    > blocks --- was that what you meant?
    
    No. We could ask brk() for large blocks.
    The problem is where to handle dynamic allocations.
    As long as they are handled by malloc we can't put
    them in proper blocks of current memory context.
    But having our own handling malloc would become useless.
    
    Vadim
    
    
  6. Re: [HACKERS] Postgres Speed or lack thereof

    Vince Vielhaber <vev@michvhf.com> — 1999-01-25T04:02:32Z

    On 25-Jan-99 Vadim Mikheev wrote:
    > 
    > Yes - I have to return to MVCC stuff...
    > So, I consider my exercizes with mmgr as vacation from MVCC -:)
    
    Dumb question.  What is MVCC?  It almost sounds like a M$ compiler.
    
    Vince.
    -- 
    ==========================================================================
    Vince Vielhaber -- KA8CSH   email: vev@michvhf.com   flame-mail: /dev/null
           # include <std/disclaimers.h>                   TEAM-OS2
       Online Searchable Campground Listings    http://www.camping-usa.com
           "There is no outfit less entitled to lecture me about bloat
                   than the federal government"  -- Tony Snow
    ==========================================================================
    
    
    
    
  7. Re: alloca (was: Postgres Speed or lack thereof)

    Marc Fournier <scrappy@hub.org> — 1999-01-25T05:38:54Z

    On Sun, 24 Jan 1999, Goran Thyni wrote:
    
    > The Hermit Hacker wrote:
    > > BUGS
    > >      The alloca() function is machine dependent; its use is discouraged.
    > 
    > Gain a big potential speed boost, loose some portability.
    > I think most modern unices has a good alloca, DOS and Mac
    > don't, but who's porting the server there?
    > 
    > Any unices out there missing alloca?
    
    Make you a deal...
    
    You build the code such that "#ifdef HAVE_ALLOCA" is true, so that those
    platforms that either don't support it, or have broken suport for it,
    aren't affect, and you are most welcome to work on it...
    
    Marc G. Fournier                                
    Systems Administrator @ hub.org 
    primary: scrappy@hub.org           secondary: scrappy@{freebsd|postgresql}.org 
    
    
    
  8. Re: [HACKERS] Re: alloca (was: Postgres Speed or lack thereof)

    Bruce Momjian <maillist@candle.pha.pa.us> — 1999-01-25T06:10:49Z

    > On Sun, 24 Jan 1999, Goran Thyni wrote:
    > 
    > > The Hermit Hacker wrote:
    > > > BUGS
    > > >      The alloca() function is machine dependent; its use is discouraged.
    > > 
    > > Gain a big potential speed boost, loose some portability.
    > > I think most modern unices has a good alloca, DOS and Mac
    > > don't, but who's porting the server there?
    > > 
    > > Any unices out there missing alloca?
    > 
    > Make you a deal...
    > 
    > You build the code such that "#ifdef HAVE_ALLOCA" is true, so that those
    > platforms that either don't support it, or have broken suport for it,
    > aren't affect, and you are most welcome to work on it...
    
    As far as I know, alloca is only useful for memory that is used by the
    current function or its children.  I don't think we have many cases
    where we could use that.
    
    -- 
      Bruce Momjian                        |  http://www.op.net/~candle
      maillist@candle.pha.pa.us            |  (610) 853-3000
      +  If your life is a hard drive,     |  830 Blythe Avenue
      +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
    
    
  9. Re: alloca (was: Postgres Speed or lack thereof)

    Goran Thyni <goran@kirra.net> — 1999-01-26T16:39:36Z

    The Hermit Hacker wrote:
    > Make you a deal...
    > 
    > You build the code such that "#ifdef HAVE_ALLOCA" is true, so that those
    > platforms that either don't support it, or have broken suport for it,
    > aren't affect, and you are most welcome to work on it...
    
    Yeah right, I should keep my mouth shut. :-)
    
    It is a big job, starting getting with getting profiling working on 
    my box, analyzing lots of code and then come up with some optimations.
    
    We can start with the patch below to detect alloca() in autoconf.
    
    	best regards,
    -- 
    -----------------
    Göran Thyni
    This is Penguin Country. On a quiet night you can hear Windows NT
    reboot!
  10. Re: [HACKERS] Re: alloca (was: Postgres Speed or lack thereof)

    Goran Thyni <goran@kirra.net> — 1999-01-26T16:43:07Z

    Bruce Momjian wrote:
    > As far as I know, alloca is only useful for memory that is used by the
    > current function or its children.  I don't think we have many cases
    > where we could use that.
    
    Perhaps not in so many obvious places, but
    with some restructuring perhaps.
    I plan to look into this too, time permitting, don't hold your breath.
    
    	regards,
    -- 
    -----------------
    Göran Thyni
    This is Penguin Country. On a quiet night you can hear Windows NT
    reboot!
    
    
    
    
  11. Re: alloca (was: Postgres Speed or lack thereof)

    Marc Fournier <scrappy@hub.org> — 1999-01-26T18:07:52Z

    
    
    Before this patch is applied, havae we determined wheteher or not its even
    a useful thing to pursue?  I thought the general conscious was that, for
    us, it wasn't...
    
     On Tue, 26 Jan 1999, Goran Thyni wrote:
    
    > The Hermit Hacker wrote:
    > > Make you a deal...
    > > 
    > > You build the code such that "#ifdef HAVE_ALLOCA" is true, so that those
    > > platforms that either don't support it, or have broken suport for it,
    > > aren't affect, and you are most welcome to work on it...
    > 
    > Yeah right, I should keep my mouth shut. :-)
    > 
    > It is a big job, starting getting with getting profiling working on 
    > my box, analyzing lots of code and then come up with some optimations.
    > 
    > We can start with the patch below to detect alloca() in autoconf.
    > 
    > 	best regards,
    > -- 
    > -----------------
    > Gran Thyni
    > This is Penguin Country. On a quiet night you can hear Windows NT
    > reboot!
    
    Marc G. Fournier                                
    Systems Administrator @ hub.org 
    primary: scrappy@hub.org           secondary: scrappy@{freebsd|postgresql}.org 
    
    
    
  12. Re: alloca (was: Postgres Speed or lack thereof)

    Goran Thyni <goran@kirra.net> — 1999-01-26T23:35:34Z

    The Hermit Hacker wrote:
    > Before this patch is applied, havae we determined wheteher or not its even
    > a useful thing to pursue?  I thought the general conscious was that, for
    > us, it wasn't...
    
    I would have to investigate further before making any final judgement.
    But having the test in configure/config.h can't hurt should me or
    someone
    else find a worthwhile speedup using alloca, can it?
    
    If you want something more substantial you have to wait,
    I just posted the patch to make it available to other
    eager investigators.
    
    	happy hacking,
    -- 
    -----------------
    Göran Thyni
    This is Penguin Country. On a quiet night you can hear Windows NT
    reboot!
    
    
  13. Re: alloca (was: Postgres Speed or lack thereof)

    Marc Fournier <scrappy@hub.org> — 1999-01-26T23:46:35Z

    On Wed, 27 Jan 1999, Goran Thyni wrote:
    
    > The Hermit Hacker wrote:
    > > Before this patch is applied, havae we determined wheteher or not its even
    > > a useful thing to pursue?  I thought the general conscious was that, for
    > > us, it wasn't...
    > 
    > I would have to investigate further before making any final judgement.
    > But having the test in configure/config.h can't hurt should me or
    > someone
    > else find a worthwhile speedup using alloca, can it?
    > 
    > If you want something more substantial you have to wait,
    > I just posted the patch to make it available to other
    > eager investigators.
    
    Let's go with the wait scenario...one thing I've always hated with other
    packages and configure is watching them run forever checking for things
    that are never used, but checking "just cause it can" *roll eyes*
    
    Marc G. Fournier                                
    Systems Administrator @ hub.org 
    primary: scrappy@hub.org           secondary: scrappy@{freebsd|postgresql}.org 
    
    
    
  14. Re: [HACKERS] Postgres Speed or lack thereof

    Massimo Dal Zotto <dz@cs.unitn.it> — 1999-01-28T09:38:10Z

    > 
    > Tom Lane wrote:
    > > 
    > > > Note that our mmgr adds 16 bytes to each allocation
    > > > (+ some bytes in malloc) - a great overhead, yes?
    > > 
    > > Youch ... for a list-node-sized request, that's a lot of overhead.
    > 
    > And lists are very often used by planner and - never pfreed.
    > 
    > > Getting this right is probably going to take some thought and work,
    > > but it looks worthwhile from a performance standpoint.  Maybe for 6.6?
    > 
    > Yes - I have to return to MVCC stuff...
    > So, I consider my exercizes with mmgr as vacation from MVCC -:)
    > 
    > > > It shows that we should get rid of system malloc/free and do
    > > > all things in mmgr itself - this would allow us much faster
    > > > free memory contexts at statement/transaction end.
    > > 
    > > I don't think we can or should stop using malloc(), but we can
    > > ask it for large blocks and do our own allocations inside those
    > > blocks --- was that what you meant?
    > 
    > No. We could ask brk() for large blocks.
    > The problem is where to handle dynamic allocations.
    > As long as they are handled by malloc we can't put
    > them in proper blocks of current memory context.
    > But having our own handling malloc would become useless.
    > 
    > Vadim
    
    We could use 4 methods for dynamic allocation:
    
    1)	malloc/free - for persistent storage allocation
    
    2)	palloc/pfree - for storage belonging to some context and
    	which we can keep track of and free explicitly
    
    3)	fast_palloc - for storage which impossible, too difficult or too
    	expensive to keep track of. This storage should be allocated with
    	fast and simple inline code from bigger chunks allocated with palloc.
    	This storage would never freed explicitly, so that code could be
    	simple and fast, but the big chunks would be freed automatically at
    	the end of the transaction.
    
    4)	fast_talloc - we could introduce a `tuple' context handled like
    	fast_palloc for storage used only while processing one tuple.
    	This storage could be fast allocated from few big chunks allocated
    	with palloc and freed explicitly after the tuple has been processed.
    	This could avoid the overhead of many malloc/palloc while reducing
    	the overall memory usage for transaction which process many rows.
    	The total cost per tuple could be one palloc and one pfree.
    	We could also simply reuse the chunks for every tuple and pfree them 
    	only at the end of the transaction. This would cost one palloc/pfree
    	per transaction.
    
    This would require revising the code and changing palloc/pfree with the new
    functions where appropriate, but this could be done gradually because the
    old palloc/pfree are always safe.
    
    -- 
    Massimo Dal Zotto
    
    +----------------------------------------------------------------------+
    |  Massimo Dal Zotto               email: dz@cs.unitn.it               |
    |  Via Marconi, 141                phone: ++39-0461534251              |
    |  38057 Pergine Valsugana (TN)      www: http://www.cs.unitn.it/~dz/  |
    |  Italy                             pgp: finger dz@tango.cs.unitn.it  |
    +----------------------------------------------------------------------+
    
    
  15. Re: [HACKERS] Postgres Speed or lack thereof

    Bruce Momjian <maillist@candle.pha.pa.us> — 1999-07-07T01:25:48Z

    I have added this to the TODO list:
    
    * improve dynamic memory allocation by introducing tuple-context memory 
      allocation
    * add pooled memory allocation where allocations are freed only as a
      group 
    
    
    
    > We could use 4 methods for dynamic allocation:
    > 
    > 1)	malloc/free - for persistent storage allocation
    > 
    > 2)	palloc/pfree - for storage belonging to some context and
    > 	which we can keep track of and free explicitly
    > 
    > 3)	fast_palloc - for storage which impossible, too difficult or too
    > 	expensive to keep track of. This storage should be allocated with
    > 	fast and simple inline code from bigger chunks allocated with palloc.
    > 	This storage would never freed explicitly, so that code could be
    > 	simple and fast, but the big chunks would be freed automatically at
    > 	the end of the transaction.
    > 
    > 4)	fast_talloc - we could introduce a `tuple' context handled like
    > 	fast_palloc for storage used only while processing one tuple.
    > 	This storage could be fast allocated from few big chunks allocated
    > 	with palloc and freed explicitly after the tuple has been processed.
    > 	This could avoid the overhead of many malloc/palloc while reducing
    > 	the overall memory usage for transaction which process many rows.
    > 	The total cost per tuple could be one palloc and one pfree.
    > 	We could also simply reuse the chunks for every tuple and pfree them 
    > 	only at the end of the transaction. This would cost one palloc/pfree
    > 	per transaction.
    > 
    > This would require revising the code and changing palloc/pfree with the new
    > functions where appropriate, but this could be done gradually because the
    > old palloc/pfree are always safe.
    > 
    > -- 
    > Massimo Dal Zotto
    > 
    > +----------------------------------------------------------------------+
    > |  Massimo Dal Zotto               email: dz@cs.unitn.it               |
    > |  Via Marconi, 141                phone: ++39-0461534251              |
    > |  38057 Pergine Valsugana (TN)      www: http://www.cs.unitn.it/~dz/  |
    > |  Italy                             pgp: finger dz@tango.cs.unitn.it  |
    > +----------------------------------------------------------------------+
    > 
    > 
    
    
    -- 
      Bruce Momjian                        |  http://www.op.net/~candle
      maillist@candle.pha.pa.us            |  (610) 853-3000
      +  If your life is a hard drive,     |  830 Blythe Avenue
      +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026