mirror of
https://github.com/postgres/postgres.git
synced 2025-06-01 14:21:49 +03:00
Modify local buffer management to request memory for local buffers in blocks
of increasing size, instead of one at a time. This reduces the memory management overhead when num_temp_buffers is large: in the previous coding we would actually waste 50% of the space used for temp buffers, because aset.c would round the individual requests up to 16K. Problem noted while studying a performance issue reported by Steven Flatt. Back-patch as far as 8.1 --- older versions used few enough local buffers that the issue isn't significant for them.
This commit is contained in:
parent
f1d8828e3c
commit
34aabc2071
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.70.2.2 2005/11/22 18:23:18 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.70.2.3 2006/12/27 22:32:03 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -48,6 +48,7 @@ static HTAB *LocalBufHash = NULL;
|
|||||||
|
|
||||||
|
|
||||||
static void InitLocalBuffers(void);
|
static void InitLocalBuffers(void);
|
||||||
|
static Block GetLocalBufferStorage(void);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -167,12 +168,8 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
|
|||||||
*/
|
*/
|
||||||
if (LocalBufHdrGetBlock(bufHdr) == NULL)
|
if (LocalBufHdrGetBlock(bufHdr) == NULL)
|
||||||
{
|
{
|
||||||
char *data;
|
|
||||||
|
|
||||||
data = (char *) MemoryContextAlloc(TopMemoryContext, BLCKSZ);
|
|
||||||
|
|
||||||
/* Set pointer for use by BufferGetBlock() macro */
|
/* Set pointer for use by BufferGetBlock() macro */
|
||||||
LocalBufHdrGetBlock(bufHdr) = (Block) data;
|
LocalBufHdrGetBlock(bufHdr) = GetLocalBufferStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -343,6 +340,54 @@ InitLocalBuffers(void)
|
|||||||
NLocBuffer = nbufs;
|
NLocBuffer = nbufs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GetLocalBufferStorage - allocate memory for a local buffer
|
||||||
|
*
|
||||||
|
* The idea of this function is to aggregate our requests for storage
|
||||||
|
* so that the memory manager doesn't see a whole lot of relatively small
|
||||||
|
* requests. Since we'll never give back a local buffer once it's created
|
||||||
|
* within a particular process, no point in burdening memmgr with separately
|
||||||
|
* managed chunks.
|
||||||
|
*/
|
||||||
|
static Block
|
||||||
|
GetLocalBufferStorage(void)
|
||||||
|
{
|
||||||
|
static char *cur_block = NULL;
|
||||||
|
static int next_buf_in_block = 0;
|
||||||
|
static int num_bufs_in_block = 0;
|
||||||
|
static int total_bufs_allocated = 0;
|
||||||
|
|
||||||
|
char *this_buf;
|
||||||
|
|
||||||
|
Assert(total_bufs_allocated < NLocBuffer);
|
||||||
|
|
||||||
|
if (next_buf_in_block >= num_bufs_in_block)
|
||||||
|
{
|
||||||
|
/* Need to make a new request to memmgr */
|
||||||
|
int num_bufs;
|
||||||
|
|
||||||
|
/* Start with a 16-buffer request; subsequent ones double each time */
|
||||||
|
num_bufs = Max(num_bufs_in_block * 2, 16);
|
||||||
|
/* But not more than what we need for all remaining local bufs */
|
||||||
|
num_bufs = Min(num_bufs, NLocBuffer - total_bufs_allocated);
|
||||||
|
/* And don't overflow MaxAllocSize, either */
|
||||||
|
num_bufs = Min(num_bufs, MaxAllocSize / BLCKSZ);
|
||||||
|
|
||||||
|
/* Allocate space from TopMemoryContext so it never goes away */
|
||||||
|
cur_block = (char *) MemoryContextAlloc(TopMemoryContext,
|
||||||
|
num_bufs * BLCKSZ);
|
||||||
|
next_buf_in_block = 0;
|
||||||
|
num_bufs_in_block = num_bufs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate next buffer in current memory block */
|
||||||
|
this_buf = cur_block + next_buf_in_block * BLCKSZ;
|
||||||
|
next_buf_in_block++;
|
||||||
|
total_bufs_allocated++;
|
||||||
|
|
||||||
|
return (Block) this_buf;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AtEOXact_LocalBuffers - clean up at end of transaction.
|
* AtEOXact_LocalBuffers - clean up at end of transaction.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user