Em seg., 19 de jul. de 2021 às 17:56, Andres Freund <andres@anarazel.de> escreveu:
Hi,
On 2021-07-18 19:23:31 +0200, Tomas Vondra wrote: > Sounds great! Thanks for investigating this and for the improvements. > > It might be good to do some experiments to see how the changes affect memory > consumption for practical workloads. I'm willing to spend soem time on that, > if needed.
I've attached my changes. They're in a rough shape right now, but I think good enough for an initial look.
Hi Andres, I take a look.
Perhaps you would agree with me that in the most absolute of times, malloc will not fail. So it makes more sense to test: if (ret != NULL) than if (ret == NULL)
What might help branch prediction. With this change wins too, the possibility to reduce the scope of some variable.
Example: +static void * pg_noinline +AllocSetAllocLarge(AllocSet set, Size size, int flags) +{ + AllocBlock block; + Size chunk_size; + Size blksize; + + /* check size, only allocation path where the limits could be hit */ + MemoryContextCheckSize(&set->header, size, flags); + + AssertArg(AllocSetIsValid(set)); + + chunk_size = MAXALIGN(size); + blksize = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ; + block = (AllocBlock) malloc(blksize); + if (block != NULL) + { + AllocChunk chunk; + + set->header.mem_allocated += blksize; + + block->aset = set; + block->freeptr = block->endptr = ((char *) block) + blksize; + + /* + * Stick the new block underneath the active allocation block, if any, + * so that we don't lose the use of the space remaining therein. + */ + if (set->blocks != NULL) + { + block->prev = set->blocks; + block->next = set->blocks->next; + if (block->next) + block->next->prev = block; + set->blocks->next = block; + } + else + { + block->prev = NULL; + block->next = NULL; + set->blocks = block; + } + + chunk = (AllocChunk) (((char *) block) + ALLOC_BLOCKHDRSZ); + chunk->size = chunk_size; + + return AllocSetAllocReturnChunk(set, size, chunk, chunk_size); + } + + return NULL; +}