[patch] bufmgr Half state CAS
Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.
You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:
docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t254114psql -h localhost -U postgresBuilt from patchset v1 (message #1), October 14, 2026 at 09:15 PM.
Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:
git clone --branch t254114_1 https://github.com/hackorum-dev/postgres.gitIn a checkout you already have, add the fork once:
git remote add hackorum https://github.com/hackorum-dev/postgres.gitthen, for this patchset and every later one:
git fetch hackorum t254114_1 && git checkout t254114_1Patchset v1 (message #1) is on t254114_1
Currently Buffer header state is a 64-bit, but it is conceptually a bit
field structure.
The CAS loops care about only some of those bits, however by operating
on a 64-bit structure unrelated field changes will cause a retry.
The atomic operations don't support a comparison mask, but in this case
we can at least CAS 32-bit, low and high half separately, reducing the
likelihood
of retrial.
Regards,
Alexandre.
On 08/10/2026 23:03, Alexandre Felipe wrote:
Currently Buffer header state is a 64-bit, but it is conceptually a bit
field structure.
The CAS loops care about only some of those bits, however by operating
on a 64-bit structure unrelated field changes will cause a retry.The atomic operations don't support a comparison mask, but in this case
we can at least CAS 32-bit, low and high half separately, reducing the
likelihood
of retrial.
Got benchmarks? I seriously doubt that you'd see any performance benefit
from this. I wouldn't be surprised if this was even slower.
- Heikki
---------- Forwarded message ---------
From: Alexandre Felipe <o.alexandre.felipe@gmail.com>
Date: Sat, Oct 10, 2026, 22:39
Subject: Re: [patch] bufmgr Half state CAS
To: Heikki Linnakangas <hlinnaka@iki.fi>
Hi Heikki, thank you for the attention
On Fri, Oct 9, 2026 at 11:40 PM Heikki Linnakangas <hlinnaka@iki.fi> wrote:
On 08/10/2026 23:03, Alexandre Felipe wrote:
Currently Buffer header state is a 64-bit, but it is conceptually a bit
field structure.
The CAS loops care about only some of those bits, however by operating
on a 64-bit structure unrelated field changes will cause a retry.The atomic operations don't support a comparison mask, but in this case
we can at least CAS 32-bit, low and high half separately, reducing the
likelihood
of retrial.Got benchmarks?
See attached, running on top of 10cc5aa96a6 I got
clients base patched
1 3251.2 3221.3
8 2592.2 3979.0 *+53.5%*
With 1 CPU there can still benefit a little bit the fast path on
BufUnlockEx,
However, that can add some cost for the cases where set_bits is not constant
and the compiler would emit an extra branch.
With many CPUs is where it really helps, e.g. one backend trying
to lock while another is trying to unpin the same buffer.
To be honest, I wasn't confident that this would show up on benchmarks,
so I didn't bother to try.
I wouldn't be surprised if this was even slower.
Do you see any mechanism by which it could become slower?
I can see only one: In UnlockBufHdrExt, if the branches are not eliminated
by the compiler. And I can can see one case in TerminateBufferIO where
it is not possible.
Attachments:
Import Notes
Reply to msg id not found: CAE8JnxPPvHOLRvzE6UchEB=ogz4z+zKUmhFMLBXQws824z2W5g@mail.gmail.com
Hi,
On 2026-10-14 21:53:21 +0100, Alexandre Felipe wrote:
See attached, running on top of 10cc5aa96a6 I got
clients base patched
1 3251.2 3221.3
8 2592.2 3979.0 *+53.5%*
Given how low the throughput is, you must be testing read/write pgbench. Is
that right? If so, it's completely inconceivable that that lwock efficiency
has that kind of impact at such low throughput & concurrency. You're waiting
for the disk, not a CAS retry. It'd be more likely that what you're measuring
WAL file initialization overhead or such.
There's no way that you'd ever see any meaningful benefits of something like
this until you reach much much higher concurrency. The timeframe between
reading the "old" value and the CAS is very short, it's pretty hard to steal
the cacheline in that window and modify it.
Greetings,
Andres Freund