Re: Reducing the chunk header sizes on all memory context types - Mailing list pgsql-hackers
From | Tomas Vondra |
---|---|
Subject | Re: Reducing the chunk header sizes on all memory context types |
Date | |
Msg-id | 60560f75-8b15-a7cc-67bc-a7bf3e8472ee@enterprisedb.com Whole thread Raw |
In response to | Re: Reducing the chunk header sizes on all memory context types (David Rowley <dgrowleyml@gmail.com>) |
Responses |
Re: Reducing the chunk header sizes on all memory context types
|
List | pgsql-hackers |
On 8/31/22 00:40, David Rowley wrote: > On Wed, 31 Aug 2022 at 02:17, Tom Lane <tgl@sss.pgh.pa.us> wrote: >> >> I wrote: >>> So maybe we should revisit the question. It'd be worth collecting some >>> stats about how much extra space would be needed if we force there >>> to be room for a sentinel. >> >> Actually, after ingesting more caffeine, the problem with this for aset.c >> is that the only way to add space for a sentinel that didn't fit already >> is to double the space allocation. That's a little daunting, especially >> remembering how many places deliberately allocate power-of-2-sized >> arrays. > > I decided to try and quantify that by logging the size, MAXALIGN(size) > and the power of 2 size during AllocSetAlloc and GenerationAlloc. I > made the pow2_size 0 in GenerationAlloc and in AlloocSetAlloc when > size > allocChunkLimit. > > After running make installcheck, grabbing the records out the log and > loading them into Postgres, I see that if we did double the pow2_size > when there's no space for the sentinel byte then we'd go from > allocating a total of 10.2GB all the way to 16.4GB (!) of > non-dedicated block aset.c allocations. > > select > round(sum(pow2_Size)::numeric/1024/1024/1024,3) as pow2_size, > round(sum(case when maxalign_size=pow2_size then pow2_size*2 else > pow2_size end)::numeric/1024/1024/1024,3) as method1, > round(sum(case when maxalign_size=pow2_size then pow2_size+8 else > pow2_size end)::numeric/1024/1024/1024,3) as method2 > from memstats > where pow2_size > 0; > pow2_size | method1 | method2 > -----------+---------+--------- > 10.194 | 16.382 | 10.463 > > if we did just add on an extra 8 bytes (or or MAXALIGN(size+1) at > least), then that would take the size up to 10.5GB. > I've been experimenting with this a bit too, and my results are similar, but not exactly the same. I've logged all Alloc/Realloc calls for the two memory contexts, and when I aggregated the results I get this: f | size | pow2(size) | pow2(size+1) -----------------+----------+------------+-------------- AllocSetAlloc | 23528 | 28778 | 31504 AllocSetRelloc | 761 | 824 | 1421 GenerationAlloc | 68 | 90 | 102 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. I also did a quick hack to see if always having the sentinel detects any pre-existing issues, but that didn't happen. I guess valgrind would find those, but not sure? regards -- Tomas Vondra EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company
Attachment
pgsql-hackers by date: