On Thu, 1 Sept 2022 at 08:53, Tomas Vondra
<tomas.von...@enterprisedb.com> wrote:
> So the raw size (what we asked for) is ~23.5GB, but in practice we
> allocate ~28.8GB because of the pow-of-2 logic. And by adding the extra
> 1B we end up allocating 31.5GB. That doesn't seem like a huge increase,
> and it's far from the +60% you got.
>
> I wonder where does the difference come - I did make installcheck too,
> so how come you get 10/16GB, and I get 28/31GB? My patch is attached,
> maybe I did something silly.

The reason my reported results were lower is because I ignored size >
allocChunkLimit allocations. These are not raised to the next power of
2, so I didn't think they should be included.

I'm not sure why you're seeing only a 3GB additional overhead. I
noticed a logic error in my query where I was checking
maxaligned_size=pow2_size and doubling that to give sentinel space.
That really should have been "case size=pow2_size then pow2_size * 2
else pow2_size end", However, after adjusting the query, it does not
seem to change the results much:

postgres=# select
postgres-# round(sum(pow2_Size)::numeric/1024/1024/1024,3) as pow2_size,
postgres-# round(sum(case when size=pow2_size then pow2_size*2 else
pow2_size end)::numeric/1024/1024/1024,3) as method1,
postgres-# round(sum(case when size=pow2_size then pow2_size+8 else
pow2_size end)::numeric/1024/1024/1024,3) as method2
postgres-# from memstats
postgres-# where pow2_size > 0;
 pow2_size | method1 | method2
-----------+---------+---------
    10.269 |  16.322 |  10.476

I've attached the crude patch I came up with for this.  For some
reason it was crashing on Linux, but it ran ok on Windows, so I used
the results from that instead.  Maybe that accounts for some
differences as e.g sizeof(long) == 4 on 64-bit windows. I'd be
surprised if that accounted for so many GBs though.

I also forgot to add code to GenerationRealloc and AllocSetRealloc

David
diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c
index b6eeb8abab..f4977f9bcc 100644
--- a/src/backend/utils/mmgr/aset.c
+++ b/src/backend/utils/mmgr/aset.c
@@ -46,6 +46,7 @@
 
 #include "postgres.h"
 
+#include "miscadmin.h"
 #include "port/pg_bitutils.h"
 #include "utils/memdebug.h"
 #include "utils/memutils.h"
@@ -696,9 +697,22 @@ AllocSetAlloc(MemoryContext context, Size size)
        int                     fidx;
        Size            chunk_size;
        Size            blksize;
+       static int      rlevel = 1;
 
        AssertArg(AllocSetIsValid(set));
 
+       if (rlevel == 1 && GetProcessingMode() == NormalProcessing)
+       {
+               rlevel++;
+               elog(LOG, "AllocSetAlloc,%s,%zu,%zu,%zu,%zu",
+                        context->name,
+                        size,
+                        MAXALIGN(size),
+                        size > set->allocChunkLimit ? 0 : 
GetChunkSizeFromFreeListIdx(AllocSetFreeIndex(size)),
+                        set->allocChunkLimit);
+               rlevel--;
+       }
+
        /*
         * If requested size exceeds maximum for chunks, allocate an entire 
block
         * for this request.
diff --git a/src/backend/utils/mmgr/generation.c 
b/src/backend/utils/mmgr/generation.c
index b39894ec94..9c5ff3c095 100644
--- a/src/backend/utils/mmgr/generation.c
+++ b/src/backend/utils/mmgr/generation.c
@@ -36,6 +36,7 @@
 #include "postgres.h"
 
 #include "lib/ilist.h"
+#include "miscadmin.h"
 #include "port/pg_bitutils.h"
 #include "utils/memdebug.h"
 #include "utils/memutils.h"
@@ -344,6 +345,18 @@ GenerationAlloc(MemoryContext context, Size size)
        MemoryChunk *chunk;
        Size            chunk_size = MAXALIGN(size);
        Size            required_size = chunk_size + Generation_CHUNKHDRSZ;
+       static int      rlevel = 1;
+
+       if (rlevel == 1 && GetProcessingMode() == NormalProcessing)
+       {
+               rlevel++;
+               elog(LOG, "GenerationAlloc,%s,%zu,%zu,0,%zu",
+                        context->name,
+                        size,
+                        MAXALIGN(size),
+                        set->allocChunkLimit);
+               rlevel--;
+       }
 
        /* is it an over-sized chunk? if yes, allocate special block */
        if (chunk_size > set->allocChunkLimit)

Reply via email to