Re: slab allocator performance issues - Mailing list pgsql-hackers

From Ranier Vilela
Subject Re: slab allocator performance issues
Date
Msg-id CAEudQAoxXwPMmk0_TYN5m8yKP09H=LHjC43WkEjZeV+7QpzxJg@mail.gmail.com
Whole thread Raw
In response to Re: slab allocator performance issues  (Andres Freund <andres@anarazel.de>)
Responses Re: slab allocator performance issues
List pgsql-hackers
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;
+}

regards,
Ranier Vilela

pgsql-hackers by date:

Previous
From: Andres Freund
Date:
Subject: Re: slab allocator performance issues
Next
From: Ranier Vilela
Date:
Subject: Micro-optimizations to avoid some strlen calls.