mirror of
https://github.com/postgres/postgres.git
synced 2025-11-19 13:42:17 +03:00
Optimize GenerationAlloc() and SlabAlloc()
In a similar effort to 413c18401, separate out the hot and cold paths in
GenerationAlloc() and SlabAlloc() to avoid having to setup the stack frame
for the hot path.
This additionally adjusts how we use the GenerationContext's freeblock.
Freeblock, when set, is now always empty and we only switch to using it
when the current allocation request finds the current block does not have
enough space and the freeblock is large enough to accomodate the
allocation.
This commit also adjusts GenerationFree() so that if we pfree the final
allocation in the current generation block, we now mark that block as
empty and keep it as the current block. Previously we free'd that block
and set the current block to NULL. Doing that meant we needed a special
case in GenerationAlloc to check if GenerationContext.block was NULL.
So this both reduces free/malloc calls and reduces the work done in
GenerationAlloc().
In passing, improve some comments in aset.c
Discussion: https://postgr.es/m/CAApHDvpHVSJqqb4B4OZLixr=CotKq-eKkbwZqvZVo_biYvUvQA@mail.gmail.com
This commit is contained in:
@@ -943,8 +943,9 @@ AllocSetAllocFromNewBlock(MemoryContext context, Size size, int flags,
|
||||
|
||||
/*
|
||||
* AllocSetAlloc
|
||||
* Returns pointer to allocated memory of given size or NULL if
|
||||
* request could not be completed; memory is added to the set.
|
||||
* Returns a pointer to allocated memory of given size or raises an ERROR
|
||||
* on allocation failure, or returns NULL when flags contains
|
||||
* MCXT_ALLOC_NO_OOM.
|
||||
*
|
||||
* No request may exceed:
|
||||
* MAXALIGN_DOWN(SIZE_MAX) - ALLOC_BLOCKHDRSZ - ALLOC_CHUNKHDRSZ
|
||||
@@ -955,11 +956,12 @@ AllocSetAllocFromNewBlock(MemoryContext context, Size size, int flags,
|
||||
* return space that is marked NOACCESS - AllocSetRealloc has to beware!
|
||||
*
|
||||
* This function should only contain the most common code paths. Everything
|
||||
* else should be in pg_noinline helper functions, thus avoiding the overheads
|
||||
* creating a stack frame for the common cases. Allocating memory is often a
|
||||
* bottleneck in many workloads, so avoiding stack frame setup is worthwhile.
|
||||
* Helper functions should always directly return the newly allocated memory
|
||||
* so that we can just return that address directly as a tail call.
|
||||
* else should be in pg_noinline helper functions, thus avoiding the overhead
|
||||
* of creating a stack frame for the common cases. Allocating memory is often
|
||||
* a bottleneck in many workloads, so avoiding stack frame setup is
|
||||
* worthwhile. Helper functions should always directly return the newly
|
||||
* allocated memory so that we can just return that address directly as a tail
|
||||
* call.
|
||||
*/
|
||||
void *
|
||||
AllocSetAlloc(MemoryContext context, Size size, int flags)
|
||||
|
||||
Reference in New Issue
Block a user